完全背包问题

    科技2025-06-13  27

    题目描述

    有n种重量和价值分别为w[i],v[i]的物品,从这些物品中挑选总重量不超过W的物品,求挑出物品价值总和的最大值。在这里,每种物品可以挑选多次。 限制条件 1 <= n <=100 1<= w[i],v[i] <= 100 1<=W<=10000

    输入

    n,w w[i],v[i]

    输出

    价值总和的最大值

    样例输入

    3 7 3 4 4 5 2 3

    样例输出

    10

    代码

    #include <algorithm> #include <iostream> #include <cstdio> using namespace std; const int N = 1010; int dp[N][N]; int W[N],V[N]; int main() { int n,m; scanf("%d%d",&n,&m); for(int i = 1;i<=n;i++) { scanf("%d%d",&W[i],&V[i]); } for(int i = 1;i<=n;i++) { for(int j = 0;j<=m;j++) { for(int k = 0;k*W[i]<=j;k++) { dp[i][j] = max(dp[i][j],dp[i-1][j-k*W[i]]+k*V[i]); } } } printf("%d\n",dp[n][m]); return 0; } 这个代码有三种循环,时间超限,然后想办法去掉k循环 f[i , j ] = max( f[i-1,j] , f[i-1,j-v]+w , f[i-1,j-2*v]+2*w , f[i-1,j-3*v]+3*w , .....) f[i , j-v]= max( f[i-1,j-v] , f[i-1,j-2*v] + w , f[i-1,j-2*v]+2*w , .....) 由上两式,可得出如下递推关系: f[i][j]=max(f[i,j-v]+w , f[i-1][j])

    优化后的代码

    #include <algorithm> #include <iostream> #include <cstdio> using namespace std; const int N = 1010; int dp[N][N]; int W[N],V[N]; int main() { int n,m; scanf("%d%d",&n,&m); for(int i = 1;i<=n;i++) { scanf("%d%d",&W[i],&V[i]); } for(int i = 1;i<=n;i++) { for(int j = 0;j<=m;j++) { dp[i][j] = dp[i-1][j]; if(j>=W[i]) { dp[i][j] = max(dp[i][j],dp[i][j-W[i]]+V[i]); } } } printf("%d\n",dp[n][m]); return 0; }

    还可以再优化一下

    #include <algorithm> #include <iostream> #include <cstdio> using namespace std; const int N = 1010; int dp[N]; int W[N],V[N]; int main() { int n,m; scanf("%d%d",&n,&m); for(int i = 1;i<=n;i++) { scanf("%d%d",&W[i],&V[i]); } for(int i = 1;i<=n;i++) { for(int j = W[i];j<=m;j++) { dp[j] = max(dp[j],dp[j-W[i]]+V[i]); } } printf("%d\n",dp[m]); return 0; }

    再将输入输出优化一下

    #include <algorithm> #include <iostream> #include <cstdio> using namespace std; const int N = 1010; int dp[N]; int main() { int n,m; scanf("%d%d",&n,&m); for(int i = 1;i<=n;i++) { int W,V; scanf("%d%d",&W,&V); for(int j = W;j<=m;j++) { dp[j] = max(dp[j],dp[j-W]+V); } } printf("%d\n",dp[m]); return 0; }
    Processed: 0.013, SQL: 8