[动态规划]0-1背包问题

来源:互联网 发布:java游戏大合集 编辑:程序博客网 时间:2024/05/17 05:11

0-1背包问题非递归解法

在不需要刚好装满情况

复杂度O(NW)

代码:

#include<stdio.h>#include<string.h>#define W 1001#define N 101int Max(int a,int b){return a>b?a:b;}int main(){int wi[N],val[N];//物品重量及价值 int dp[N][W];int weight,n;//背包总重量及物品数量 int i,j,k,w;while(scanf("%d%d",&weight,&n)!=EOF){memset(wi,0,sizeof(wi));memset(val,0,sizeof(val));memset(dp,0,sizeof(dp));for(i=0;i<n;i++){scanf("%d%d",&wi[i],&val[i]);}for(w=0;w<=weight;w++)if(wi[0]<=w) dp[0][w]=val[0];for(i=1;i<n;i++){for(w=0;w<=weight;w++){if(wi[i]<=w)dp[i][w]=Max(dp[i-1][w-wi[i]]+val[i],dp[i-1][w]);else dp[i][w]=dp[i-1][w];}}printf("%d\n",dp[n-1][weight]);}return 0; }
空间复杂度优化O(W)

代码:

#include<stdio.h>#include<string.h>#define W 1001#define N 101int Max(int a,int b){return a>b?a:b;}int main(){int wi[N],val[N];//物品重量及价值 int dp[W];int weight,n;//背包总重量及物品数量 int i,j,k,w;while(scanf("%d%d",&weight,&n)!=EOF){memset(wi,0,sizeof(wi));memset(val,0,sizeof(val));memset(dp,0,sizeof(dp));for(i=0;i<n;i++){scanf("%d%d",&wi[i],&val[i]);}for(i=0;i<n;i++)for(w=weight;w>=wi[i];w--)dp[w]=Max(dp[w-wi[i]]+val[i],dp[w]);printf("%d\n",dp[weight]);}return 0; }

记录放入物品

代码:

#include<stdio.h>#include<string.h>#define W 1001#define N 101int Max(int a,int b){return a>b?a:b;}int main(){int wi[N],val[N];//物品重量及价值 int mark[N];//记录路径 int dp[N][W];int weight,n;//背包总重量及物品数量 int i,j,k,w;while(scanf("%d%d",&weight,&n)!=EOF){memset(wi,0,sizeof(wi));memset(val,0,sizeof(val));memset(dp,0,sizeof(dp));for(i=0;i<n;i++){scanf("%d%d",&wi[i],&val[i]);}for(w=0;w<=weight;w++)if(wi[0]<=w) dp[0][w]=val[0];for(i=1;i<n;i++){for(w=0;w<=weight;w++){if(wi[i]<=w)dp[i][w]=Max(dp[i-1][w-wi[i]]+val[i],dp[i-1][w]);else dp[i][w]=dp[i-1][w];}}j=weight;memset(mark,0,sizeof(mark));for(i=n-1;i>=0;i--){if(dp[i][j]>dp[i-1][j]){mark[i]=1;j=j-wi[i];}}printf("%d\n",dp[n-1][weight]);for(i=0;i<n-1;i++){if(mark[i]==1) printf("%d\n",i+1);}}return 0; }


0 0