POJ 3172 Scales (dfs剪枝,dp超时)

题意:有N个砝码(1<=N<=1000),每个砝码的重量(0~2^31),这些砝码有一些特点,每一个砝码的重量大于等于前两个砝码的和,给出一个重量C,要求任选一些砝码组合,

组合的重量不超过C而且尽量大,求组合的数值。

因为砝码的特点  f[n]>=f[n-2]+f[n-1],由斐波那契数列知N最多45、46项,所以1000是唬人的,如果用背包10^9数组开不出来,而且10^9*45超时,用dfs所搜,但是2^46也超时,加强剪枝

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#define nMAX 50
using namespace std;
int cap,ans,n;
int w[nMAX];
long long sum[nMAX];
void dfs(int order,int weight)
{
    if(weight<=0)return;
    if(order==1)
    {
        if(w[1]<=weight)weight-=w[1];
        ans=min(ans,weight);
        return ;
    }
    if(weight>=sum[order])
    {
        weight-=sum[order];
        ans=min(weight,ans);
        return ;
    }
    dfs(order-1,weight-w[order]);
    dfs(order-1,weight);
}
int main()
{
    int n,i;
    while(~scanf("%d%d",&n,&cap))
    {
        sum[0]=0;
        for(i=1;i<=n;i++)
        {
            scanf("%d",&w[i]);
            sum[i]=sum[i-1]+w[i];
        }

        if(cap<w[1]){printf("0\n");continue;}

        ans=(1<<30)+1;
        for(i=n;i>=1;i--)
        {
            if(cap>=w[i])break;
        }
        dfs(i,cap);
        printf("%d\n",cap-ans);
    }
    return 0;
}

  

posted @ 2012-08-16 11:48  快乐.  阅读(230)  评论(0编辑  收藏  举报