链接:Miku
------------------
这一个问题考虑为两种问题
1:剩下的砝码有什么情况?
2:能拼出多少种?
对于1:没有办法,只能爆搜所有情况
对于2:用一个改良的01背包就可以解决
--------------------
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int sum; int n; int m; int dp[30000]={1}; int a[30]; int vis[30]; int ans; int anss; void dpp(){ ans=0; memset(dp,0,sizeof(dp)); dp[0]=1; for(int i=1;i<=n;++i){ // cout<<vis[i]<<" "; if(vis[i]==0){ for(int j=sum;j>=a[i];--j){ if(dp[j-a[i]]==1&&dp[j]==0){ dp[j]=1; ans++; } } } } anss=max(anss,ans); // cout<<endl; } void dfs(int now,int k){ if(k>m) return ; if(now==n+1&&k==m){ dpp(); return ; } if(now==n+1) return ; vis[now]=1; dfs(now+1,k+1); vis[now]=0; dfs(now+1,k); } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;++i){ scanf("%d",&a[i]); sum+=a[i]; } dfs(1,0); printf("%d",anss); return 0; }