您的位置:首页 > 其它

UVA 624 CD(DP:01背包)

2014-04-02 19:21 393 查看
UVA 624 CD(DP:01背包)
题意:有N个物品,每个物品一个重量,现在问你在重量不超过W的前提下,如何选物品可以使得装的物品尽量多,并且要按输入顺序输出被装入的物品,已经总重量sum.
分析:基础的01背包DP不过需要打印路径,需要熟练.
由于dp[i][j] = max( dp[i-1][j],dp[i-1][j-wi]+wi ).所以用一个二维数组vis[i][j]表示dp[i][j]作出的选择.而且可能存在多种选择的情况,这题目好像不考虑,总是优先维持之前已经选择的物品.
注意:由于打印物品是从前往后打印,所以选物品的时候要从后往前选,则当得到dp
[nWeight]的时候可以推出第一个物品选没选.

AC代码:
#include <iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int MAXN=10005;
int weight[25];
int dp[MAXN];
int nKind,nWeight;
bool vis[25][MAXN];
void ZeroOnePack()
{
    for(int i=nKind;i>=1;i--)
        for(int j=nWeight;j>=weight[i];j--)
        {
            if(dp[j-weight[i]]+weight[i]>dp[j])
            {
                dp[j] = dp[j-weight[i]]+weight[i];
                vis[i][j]=true;
            }
        }
}
int main()
{
    while(scanf("%d%d",&nWeight,&nKind)==2)
    {
        for(int i=1;i<=nKind;i++)
            scanf("%d",&weight[i]);
        memset(dp,0,(nWeight+1)*sizeof(dp[0]));
        memset(vis,false,sizeof(vis));
        ZeroOnePack();
        int end=nWeight;
        for(int i=1;i<=nKind;i++)
        if(vis[i][end])
        {
            printf("%d ",weight[i]);
            end -=weight[i];
        }
        printf("sum:%d\n",dp[nWeight]);
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: