boolcanPartition(vector<int>& nums){ int sum = 0; for (auto n : nums) sum += n; // 若累加值为奇数,则不可能存在这样的两个子集 if (sum % 2 != 0) returnfalse; sum >>= 1; int n = nums.size(); // 判断大小为sum的背包,是否能恰好装入价值为sum的物品 // 其中,各个物品的体积和价值均为nums[i] vector<int> maxPack(sum + 1); for (auto n : nums) { if (n > sum) returnfalse; for (int i = sum; i >= n; i --) { maxPack[i] = max(maxPack[i], maxPack[i - n] + n); } } return maxPack[sum] == sum; }
一维动态规划
leetcode139 单词拆分
给你一个字符串 s 和一个字符串列表 wordDict
作为字典。如果可以利用字典中出现的一个或多个单词拼接出 s 则返回
true。
注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
boolwordBreak(string s, vector<string>& wordDict){ vector<bool> dp(s.size() + 1, false); dp[0] = true; for (int i = 1, len = s.size(); i <= len; i ++) { bool flag = false; for (string word : wordDict) { if (i < word.size()) continue; int start = i - word.size(); if (dp[start] && s.substr(start, word.size()) == word) { flag = true; break; } } dp[i] = flag; } return dp[s.size()]; }
牛客 2021360
春招编程题(第一批) 火星人的宝藏
X 星人发现了一个藏宝图,在藏宝图中标注了 N 个宝库的位置。这 N
个宝库连成了一条直线,每个宝库都有若干枚金币。 X
星人决定乘坐热气球去收集金币,热气球每次最多只能飞行 M
千米(假设热气球在飞行过程中并不会发生故障)此外,由于设计上的缺陷,热气球最多只能启动
K 次。 X 星人带着热气球来到了第 1 个宝库(达到第 1
个宝库时热气球尚未启动),收集完第 1
个宝库的金币后将启动热气球前往下一个宝库。如果他决定收集某一个宝库的金币,必须停下热气球,收集完之后再重新启动热气球。当然,X
星人每到一个宝库是一定会拿走这个宝库所有金币的。 已知每一个宝库距离第 1
个宝库的距离(单位:千米)和宝库的金币数量。 请问 X
星人最多可以收集到多少枚金币?
intmain(){ int N, M, K; while (cin >> N >> M >> K) { // 注意 while 处理多个 case vector<vector<int>> ship(N, vector<int>(2, 0)); vector<vector<int>> dp(N, vector<int>(K + 1, 0)); int k, v; for (int i = 0; i < N; i ++) { cin >> k >> v; ship[i][0] = k; ship[i][1] = v; if (i > 0 && k <= M) { dp[i][1] = max(dp[i - 1][1], v); } } if (N - 1 <= K) { longlong ret = 0; for (int i = 1; i < N; i ++) { if (ship[i][0] - ship[i - 1][0] > M) break; ret += ship[i][1]; // cout << ret << endl; } cout << ret + ship[0][1]; return0; } for (int k = 2; k <= K; k ++) { for (int n = k; n < N; n ++) { int nn = n - 1; int maxV = 0; while (nn >= k - 1) { if (dp[nn][k - 1] == 0) { nn --; continue; } if (ship[n][0] - ship[nn][0] > M) break; maxV = max(maxV, dp[nn][k - 1] + ship[n][1]); nn --; } dp[n][k] = maxV; // if (k == K) cout << "n: " << n << " k: " << k << " dp:" << dp[n][k] << endl; } } int ret = 0; for (int i = K; i < N; i ++) { ret = max(ret, dp[i][K]); } cout << ret + ship[0][1]; } return0; } // 64 位输出请用 printf("%lld")