POJ 1252 Euro Efficiency 完全背包
http://poj.org/problem?id=1252
题意:给出六种币值的硬币,尽量用少得数量组合出(1~100)的币值,输出用的硬币的平均数量和用到的最多组合时的数量
有一点,不是所有的组合都是六种硬币相加得到的,还有相减的情况,如有 1、2、5、10、20、50六种硬币,
98=50+20+20+5+2+1 , 98=50+50-2 后一种才是答案
代码:
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#define inf 10005
const int MAX=2002;
using namespace std;
int a[7],dp[MAX];
int min(int a,int b)
{
return a<b?a:b;
}
int main()
{
int CASE;
int i,j,k;
scanf("%d",&CASE);
while(CASE--)
{
for(i=1;i<=6;i++)
scanf("%d",&a[i]);
for(i=0;i<=MAX;i++)
dp[i]=inf;
dp[0]=0;
for(j=1;j<=6;j++)//完全背包
for(k=a[j];k<=MAX;k++)
{
dp[k]=min(dp[k],dp[k-a[j]]+1);
}
for(k=1;k<=6;k++)//保证大数用的硬币最少,然后从大往小减,还是完全背包的思想
for(j=MAX-a[k];j>=1;j--)
//for(i=j-a[k];i>=0;i--)//完全背包,减掉一维,运行时间减少300+MS
dp[j]=min(dp[j],dp[j+a[k]]+1);
double ans=0;
int MIN=0;
for(i=1;i<=100;i++)
{
ans+=dp[i];
MIN=MIN>dp[i]?MIN:dp[i];
}
ans/=100;
printf("%.2f %d\n",ans,MIN);
}
return 0;
}

浙公网安备 33010602011771号