Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

找到了官方的数据,要么正确要么相差1~2,求大牛帮忙看下代码吧(带注释),要崩溃了……

Posted by catcher_wang at 2009-10-22 17:25:15 on Problem 3260 and last updated at 2009-10-22 17:25:53
/*
思路:所有将硬币当作物品,容量为其面值,价值都为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:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator