题目中文,不解释,(这个ceoi貌似是欧洲的emm)
一眼背包,两眼看到longlong的数据,三眼果断弃掉dp
正解为折半暴搜,先搜前n/2小,再搜后n/2
然后一边暴搜后n/2,一边统计方案数
思路讲不清emmmmm,日后更新
#include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; long long int m,cost[50]; int n,mid,lim,cnt=0; long long int ans[2000000],que=0; int dfs1(int x,long long int sum) { if (sum>m) return 0; if (x==lim+1) { ans[++cnt]=sum; return 0; } dfs1(x+1,sum); dfs1(x+1,sum+cost[x]); return 0; } int dfs2(int x,long long int sum) { if (sum>m) return 0; if (x==lim+1) { if (ans[1]+sum>m) return 0; int l=1,r=cnt;int md=(l+r)/2,tot=0; while (l<=r) { md=(l+r)/2; if (sum+ans[md]<=m) tot=md,l=md+1; else r=md-1; } que+=tot; return 0; } dfs2(x+1,sum+cost[x]); dfs2(x+1,sum); return 0; } int main() { cin>>n>>m; for (int i=1;i<=n;i++) cin>>cost[i]; lim=mid=n/2; dfs1(1,0); sort(ans+1,ans+cnt+1); lim=n; dfs2(mid+1,0); cout<<que; return 0; }