P1441 砝码称重
考察:搜索+背包dp
思路:
枚举n中选m个的组合数.最后在用dp求n-m个数能表示的和.时间复杂度Cnm * n*2000 ,数据跑不满....
1 #include <iostream> 2 #include <cstring> 3 using namespace std; 4 const int N = 21,M = 2010,P = 5; 5 int n,m,a[N],sum,path[P],ans; 6 bool st[N],f[M]; 7 int dp() 8 { 9 memset(f,0,sizeof f); 10 f[0] = 1; 11 for(int i=1;i<=n;i++) 12 if(!st[i]) 13 for(int j=sum;j>=a[i];j--) 14 f[j] = f[j-a[i]] | f[j]; 15 int res = 0; 16 for(int i=1;i<=sum;i++) res+=f[i]; 17 return res; 18 } 19 void dfs(int sta,int cnt) 20 { 21 if(cnt==m) 22 { 23 st[path[1]] = st[path[2]] = st[path[3]] = st[path[4]] = 1; 24 ans = max(dp(),ans); 25 st[path[1]] = st[path[2]] = st[path[3]] = st[path[4]] = 0; 26 return; 27 } 28 for(int i=sta;i<=n;i++) 29 { 30 path[cnt+1] = i; 31 dfs(i+1,cnt+1); 32 path[cnt+1] = 0; 33 } 34 } 35 int main() 36 { 37 scanf("%d%d",&n,&m); 38 for(int i=1;i<=n;i++) scanf("%d",&a[i]),sum+=a[i]; 39 dfs(1,0); 40 printf("%d\n",ans); 41 return 0; 42 }