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

浙公网安备 33010602011771号