Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
找到了官方的数据,要么正确要么相差1~2,求大牛帮忙看下代码吧(带注释),要崩溃了……/* 思路:所有将硬币当作物品,容量为其面值,价值都为1,要使背包价值最小 支付的为多重背包(容量为t~t+maxv),找零的为完全背包(容量为0~maxv) 而多重背包又可以分解为完全背包和0-1背包(详见背包9讲) 当c[i]为0时,此种硬币不用于支付但可用于找零 难点:如何确定支付与找零的最大值,用了t+mavx*maxv和maxv*maxv,证明再议 */ #include<iostream> using namespace std; #define MAXN 101 #define MAXV 121 struct Node{ int v,c; }nodes[MAXN]; int n,t,bound; int receive[MAXV*MAXV]; int pay[10000+MAXV*MAXV]; int cmp(const void *a,const void *b){ return (*(Node *)a).v-(*(Node *)b).v; } void completePack(int cost,int weight,int bound,int *arr){//完全背包 for(int i=cost;i<=bound;i++) if(arr[i-cost] && (arr[i]==0 || arr[i]>arr[i-cost]+weight)) arr[i]=arr[i-cost]+weight; } void zeroOnePack(int cost,int weight,int *arr){//01背包 for(int i=bound;i>=cost;i--) if(arr[i-cost] && (arr[i]==0 || arr[i]>arr[i-cost]+weight)) arr[i]=arr[i-cost]+weight; } void multiplePack(int cost,int weight,int amount,int *arr){//多重背包 if(cost*amount>=bound){ completePack(cost,weight,bound,arr); }else{//参考背包9讲,转化为01背包,此步复杂度由O(bound*amount)减少为O(bound*log(amount)) int k=1; while(k<amount){ zeroOnePack(cost*k,k*weight,arr); amount-=k; k*=2; } zeroOnePack(cost*amount,amount*weight,arr); } } int solve(){ int i,j,ans=-1,temp; //找零部分 for(i=1;i<=n;i++)//之前因为跟支付共用一个函数,致使而receive边界比pay小,越界导致nodes全部改变 completePack(nodes[i].v,1,bound-t,receive); //支付部分 for(i=1;i<=n;i++){ if(nodes[i].c<=0) continue;//此时该类硬币不能支付但能找零 multiplePack(nodes[i].v,1,nodes[i].c,pay); } //结合支付与找零求解 for(i=t;i<=bound;i++) if(pay[i]>0 && receive[i-t]>0) if(ans==-1 || ans>pay[i]+receive[i-t]) ans=pay[i]+receive[i-t]; return ans; } int main(){ int i; scanf("%d%d",&n,&t); for(i=1;i<=n;i++){ scanf("%d",&nodes[i].v); receive[nodes[i].v]=1;//初始化,很重要,不然永远为-1 pay[nodes[i].v]=1;//同理 } for(i=1;i<=n;i++) scanf("%d",&nodes[i].c); qsort(nodes+1,n,sizeof(nodes[0]),cmp); bound=t+nodes[n].v * nodes[n].v; printf("%d\n",solve()); system("pause"); return 0; } Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator