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;
}

  

posted @ 2012-04-14 09:37  快乐.  阅读(154)  评论(0编辑  收藏  举报