POJ 3260 The Fewest Coin

FJ要買價值爲V的東西,他又N種貨幣,第i種的幣值爲Vi,數量爲Ai,老闆每種貨幣都有無數個,求最少需要多少張貨幣完成交易(FJ付出的加上老闆找零用的)

先計算FJ付x元最少要幾張貨幣(多重揹包),然後計算找y元最少需要幾張貨幣(完全揹包),然後枚舉x-y=V對應的最小值

x和y的上限我開到15000就能過了,DISCUSS上有人說Vmax*Vmax就夠,不是很明白


代碼:

#include<iostream>
#include<memory.h>
#include<string>
#include<cstdio>
#include<algorithm>
#include<math.h>
#include<stack>
#include<queue>
#include<vector>
#include<map>
using namespace std;
const int MAX=15005;
const int inf=1<<29;
int dp1[MAX],dp2[MAX],val[105],used[MAX],a[MAX];
int main()
{
	int i,j,k,V,n;
	while(scanf("%d%d",&n,&V)!=EOF)
	{
		for(i=1;i<MAX;i++)
		{
			dp1[i]=dp2[i]=inf;
		}
		dp1[0]=dp2[0]=0;
		for(i=1;i<=n;i++)
		{
			scanf("%d",&val[i]);
		}
		for(j=1;j<=n;j++)
			scanf("%d",&a[j]);
		for(i=1;i<=n;i++)
		{
			memset(used,0,sizeof(used));
			for(j=val[i];j<MAX;j++)
			{
				if(dp1[j-val[i]]+1<dp1[j]&&used[j-val[i]]<a[i])
				{
					//cout<<j<<endl;
					dp1[j]=dp1[j-val[i]]+1;
					used[j]=used[j-val[i]]+1;
				}
			}
		}
		for(i=1;i<=n;i++)
		{
			for(j=val[i];j<MAX;j++)
			{
				dp2[j]=min(dp2[j],dp2[j-val[i]]+1);
			}
		}
		int ans=inf;
		for(i=V;i<MAX;i++)
		{
			ans=min(ans,dp1[i]+dp2[i-V]);
		}
		if(ans==inf)
			ans=-1;
		printf("%d\n",ans);
	}
	return 0;
}
	



發佈了242 篇原創文章 · 獲贊 5 · 訪問量 23萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章