洛谷 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