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