【UVA】624-CD(动态规划01背包问题)

来源:互联网 发布:卫生间js防水技术交底 编辑:程序博客网 时间:2024/06/05 00:27

看了一下0/1背包问题,01背包,说白了就是选和不选的问题。

dp[i][j]代表只考虑前i个物品的情况下,重量为j的背包最优化的选择方法。

所以可以获得递推式子dp[i][j] = max(dp[i - 1][j],dp[i - 1][j - v[i]] + w[i]);

大题意思就是:是否选择拿i物品,使得只考虑前i个物品,重量为j的时候的方案最优。

    for(int i = 0 ; i <= C ; i++)  dp[0][i] = 0;    for(int i = 1; i <= n ; i++)        for(int j = 0 ; j <= C ; j++){            dp[i][j] = dp[i - 1][j];            if(j - V[i] >= 0)            dp[i][j] = max(dp[i][j],dp[i - 1][j - V[i]        }

一步一步考虑,在所有重量情况下,只选择前i中物品的最优方案。

这样的话其实不考虑打印路径的话,连V,W的值都不需要记录。

    for(int i = 0 ; i <= C ; i++)  dp[0][i] = 0;    for(int i = 1; i <= n ; i++){        scanf("%d%d",&W,&V);        for(int j = 0 ; j <= C ; j++){            dp[i][j] = dp[i - 1][j];            if(j - V >= 0)            dp[i][j] = max(dp[i][j],dp[i - 1][j - V] + W);        }    }
另外,甚至可以将其变为一维数组。

    for(int i = 1; i <= n ; i++){        scanf("%d%d",&W,&V);        for(int j = C ; j >= 0 ; j--){            if(j - V >= 0)            dp[j] = max(dp[j],dp[j - V] + W);        }    }

不过改成一维数组不论是打印路径还是理解都比较困难,就像这道题一样,不推荐使用。

624CDAcceptedC++0.025

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<map>#include<stack>#include<queue>#include<set>#include<ctime>#include<cmath>#include<string>#include<iomanip>#include<climits>#include<cctype>#include<deque>#include<list>#include<sstream>#include<vector>#include<cstdlib>using namespace std;#define _PI acos(-1.0)#define INF (1 << 30)typedef long long LL;typedef unsigned long long ULL;typedef pair<int,int> pill;/*================================================================================================*/#define MAXD 20 + 10#define MAX_SIZE 100000 + 10int V,n;int CD[MAXD];int dp[MAXD][MAX_SIZE];void init(){    scanf("%d",&n);    for(int i = 1 ; i <= n ; i++)        scanf("%d",&CD[i]);    return ;}int DP(){    int ans = 0 ;    for(int i = 0 ; i <= n ; i++){        for(int j = 0 ; j <= V ; j++){            dp[i][j] = 0;            if(i)                dp[i][j] = (i == 1 ? 0 : dp[i - 1][j]); /*这句话就是0/1背包的关键*/            if(i && (j - CD[i] >= 0)){                dp[i][j] = max(dp[i][j],dp[i - 1][j - CD[i]] + CD[i]);            }        }    }    return dp[n][V];}void print(int VX){    /*打印路径*/    int rote[MAXD];    int size = 0;    for(int i = n - 1; i >= 0 ; i--){         if(dp[i][VX - CD[i + 1]] + CD[i + 1]== dp[i + 1][VX]){                rote[size++] = CD[i + 1];                VX -= CD[i + 1];         }    }    for(int i = size - 1; i >= 0 ; i--)        printf("%d ",rote[i]);}int main(){    while(scanf("%d",&V) != EOF){      init();      int ans = DP();      print(ans);      printf("sum:%d\n",ans);    }    return 0;}

0 0
原创粉丝点击