POJ1276

Problem: Cash Machine
Description: 给你一个总的金额,然后有N种账单,每种账单又有m张,要你选出账单使得金额不超过总的金额,但是又最接近总金额。
Solution: 多重背包+二进制优化。
Code(C++):

#include 
#include 

#define MAX(a,b) ((a)>(b)? (a):(b))

const int M=110000+5;

int SUM;
int n;
int top;

int c[M];
int dp[M];

int main()
{
    while(~scanf("%d%d",&SUM,&n)){
        top=0;
        for(int i=0;iint num,C;
            scanf("%d%d",&num,&C);
            if(!num||!C)
                continue;
            int sum=1;
            while(sum*sum;
                num-=sum;
                sum<<=1;
            }
            c[++top]=num*C;
        }

        memset(dp,0,sizeof(dp));
        for(int i=1;i<=top;i++)
            for(int j=SUM;j>=c[i];j--)
                dp[j]=MAX(dp[j-c[i]]+c[i],dp[j]);
        printf("%d\n",dp[SUM]);
    }
    return 0;
}

你可能感兴趣的:(OJ,ACM算法竞赛)