UVA 624 CD(01背包/记录路径)

来源:互联网 发布:javascript库 编辑:程序博客网 时间:2024/06/06 02:17

题目链接:
UVA 624 CD
题意:
给出n个物品和总价值P,每个物品有一个价值,输出由这些物品组成价值和最接近P的价值(不能超过P)和和这些物品编号。
如果有多种方案任意输出一种。
分析:
①:先用类似01背包的思路对小于等于P的价值和进行可行性分析,然后找到最大能组成的合法价值和。根据这个价值和对原来的物品
dfs搜索。
②:在找最大价值的过程中记录组成价值和的最后一件商品编号。

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int MAX_VAL=2000;const int MAX_N=100;int v,n,res;int val[MAX_N],dp[MAX_VAL],flag[MAX_N],step[MAX_N];int main(){    freopen("uva624in.txt","r",stdin);    while(~scanf("%d%d",&v,&n)){        for(int i=1;i<=n;i++) scanf("%d",&val[i]);        memset(dp,-1,sizeof(dp));        dp[0]=0;        //dp[i]:表示可以组成总价值i的最后一件商品的编号        for(int i=1;i<=n;i++){            for(int j=v;j>=val[i];j--){                if(dp[j]==-1&&dp[j-val[i]]!=-1) dp[j]=i;            }        }        for(int i=v;i>=0;i--){            if(dp[i]!=-1){                res=i;                break;            }        }        int tmp=res,tot=-1;        while(tmp){            step[++tot]=dp[tmp];            tmp-=val[dp[tmp]];        }        for(int i=tot;i>=0;i--){            printf("%d ",val[step[i]]);        }        printf("sum:%d\n",res);    }    return 0;}
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int MAX_VAL=2000;const int MAX_N=100;int v,n,res;int val[MAX_N],dp[MAX_VAL],flag[MAX_N];inline int dfs(int k,int tmp){    if(tmp>res) return 0;    else if(tmp==res) return 1;    for(int i=k-1;i>=1;i--){        flag[i]=1;        if(dfs(i,tmp+val[i])) return 1;        flag[i]=0;    }    return 0;}int main(){    freopen("uva624in.txt","r",stdin);    while(~scanf("%d%d",&v,&n)){        //int sum=0;        for(int i=1;i<=n;i++) {            scanf("%d",&val[i]);            //sum+=val[i];        }        memset(dp,0,sizeof(dp));        dp[0]=1;        //dp[i]=1:表示可以组成总价值和i,dp[i]=0:表示不能组成总价值和i        for(int i=1;i<=n;i++){            for(int j=v;j>=val[i];j--){                if(dp[j]==0&&dp[j-val[i]]==1) dp[j]=1;            }        }        for(int i=v;i>=0;i--){            if(dp[i]==1){                res=i;                break;            }        }        for(int i=n;i>=1;i--){            memset(flag,0,sizeof(flag));            flag[i]=1;            if(dfs(i,val[i])) break;        }        for(int i=1;i<=n;i++){            if(flag[i]) printf("%d ",val[i]);        }        printf("sum:%d\n",res);    }    return 0;}
0 0
原创粉丝点击