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 }

 

posted @ 2021-04-17 14:46  acmloser  阅读(41)  评论(0编辑  收藏  举报