洛谷 P2347 砝码称重 & [NOIP1996提高组](dp,枚举)

传送门


解题思路

一看数据范围<1000就坚定了我暴力的决心(不愧是1996年代的题还是t4QAQ)

所以很显然,暴力之中有一点dp的思想,就是把它们像多重背包一样拆分,拆成a1+a2+a3+a4+a5+a6个砝码,然后枚举一遍,如果vis[j]是1也就是j这个数值可以被表示的话,那么vis[j+a[i]]也很显然可以被表示。

这里要注意一下几点:

  • 一开始要初始化vis[0]=1,枚举j时一定要到0,不然输出结果是0
  • j枚举时要从大到小枚举,否则就变成了完全背包,就会输出1000
  • 最后统计时不能统计vis[0],要从1开始

AC代码

 1 #include<iostream>
 2 using namespace std;
 3 int a[1005],num[10],ans;
 4 int fama[10]={0,1,2,3,5,10,20};
 5 bool vis[1005];
 6 int main()
 7 {
 8     int n=0;
 9     for(int i=1;i<=6;i++){
10         cin>>num[i];
11         num[0]+=num[i];
12         for(int j=1;j<=num[i];j++){
13             a[++n]=fama[i];
14         }
15     }
16     vis[0]=1;
17     for(int i=1;i<=n;i++){
18         for(int j=1000;j>=0;j--){
19             if(vis[j]) vis[j+a[i]]=1;
20         }
21     }
22     for(int i=1;i<=1000;i++) if(vis[i]) ans++;
23     cout<<"Total="<<ans;
24     return 0;
25 }

//NOIP1996提高组 t4

posted @ 2019-11-13 23:12  尹昱钦  阅读(441)  评论(0编辑  收藏  举报