有一个天平和 N 个砝码,天平的承重为 C,也就是左右两边任何一边超过 C 天平就会被破坏。称重的时候,天平的左边只能放要称的东西,砝码都放在右边。将这 N 个砝码按照质量从小到大排序后,从第 3 个砝码开始,每一个砝码的质量都不小于前两个砝码质量的和。
你想要知道,用这些砝码,在不破坏天平的情况下,最大可以称出多少质量?
1≤N≤1000,1≤Wi,C<230。
加粗的那一部分是搜索正确性的关键。斐波那契数列增长很快。经核对,数据中 N 最大为 40。
#include<cstdio>
using namespace std;
const int N=50; int n,c,ans,a[N]; long long pre[N];
inline int read() {
int x=0; char ch=getchar();
while(ch<'0'||ch>'9') ch=getchar();
while(ch>='0'&&ch<='9') { x=x*10+ch-'0'; ch=getchar(); }
return x;
}
inline void write(int x) {
if(x>=10) write(x/10);
putchar(x%10+'0');
}
inline void dfs(int step,long long sum) {
if(sum>c||sum+pre[step]<=ans) return;//最优性剪枝
if(!step) return (ans<sum?ans=sum:ans=ans),void();
dfs(step-1,sum),dfs(step-1,sum+a[step]);
}
int main() {
n=read(),c=read();
for(register int i=1;i<=n;i++) a[i]=read(),pre[i]=pre[i-1]+a[i];
dfs(n,0);
write(ans);
return 0;
}