【NOIP2006】开心的金明

绝对的水题,只是用来复习。

本题在洛谷上的链接:https://www.luogu.org/problemnew/show/P1060


 这不就是最简单的01背包吗?虽然每件物品的重要度变成了输入的重要度*物品价格。

01背包没什么好说的,多写两遍就会了,最朴素的01背包时间复杂度是O(n*m)的,空间复杂度也是O(n*m)的。原因在于此时的状态转移方程为dp[i][j]=max(dp[i-1][j],dp[i-1][j-p[i]]+v[i]),每次我们处理完一件物品时,数组中存放的就是上一件物品的dp值,如果可以加以利用,就可以省去一维。我们可以逆序枚举j,这样dp[j]=max(dp[j],dp[j-p[i]]+v[i]),每当我们处理到dp[j]时,此时的dp[j]中存放的其实就是dp[i][j]。时间复杂度就很难优化了。

 1 #include <cstdio>
 2 
 3 const int maxn = 3e4 + 5, maxm = 30;
 4 
 5 int v[maxm], p[maxm], dp[maxn];
 6 
 7 int main() {
 8     int n, m;
 9     scanf("%d%d", &n, &m);
10     for (int i = 1; i <= m; ++i) {
11         scanf("%d%d", &v[i], &p[i]);
12         for (int j = n; j >= v[i]; --j)
13             if (dp[j] < dp[j - v[i]] + v[i] * p[i])
14                 dp[j] = dp[j - v[i]] + v[i] * p[i];
15     }
16     printf("%d", dp[n]);
17     return 0;
18 }
AC代码
原文地址:https://www.cnblogs.com/Mr94Kevin/p/9588215.html