蓝桥杯试题 历届真题 砝码称重【第十二届】【省赛】【B组】

题目链接:http://lx.lanqiao.cn/problem.page?gpid=T2893

0/1背包的变种题,dp思想的具体体现

我们可以用dp[i][j]来表示i个砝码能称j种重量,因为是进行个数统计,所以我们用逻辑(bool)数组来进行情况的判定,最后用ans进行统计后输出即可;

注意的是,如何进行是否满足条件的时候,我们对bool数组的统计进行了或运算,

何为或运算:就是当两者其中有一个为1的时候,这个式子的结果就是1;

例如3|=0,结果就是1;

参考代码如下:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n;
 4 int m;//重量上限,即所有砝码的重量都不会超出这个限度 
 5 int ans;
 6 bool dp[300][100010];//dp[i][j]表示前i个砝码如果能称j的重量就为true,反之为false 
 7 int a[300];
 8 int main()
 9 {
10     ios::sync_with_stdio(false);
11     cin>>n;
12     for(register int i=1;i<=n;i++)
13     {
14         cin>>a[i];
15         m+=a[i];//累加砝码重量 
16     }
17     dp[0][0]=true;//当砝码个数为0的时候能称0的重量 
18     for(register int i=1;i<=n;i++)
19     {
20         for(register int j=0;j<=m;j++)
21         {
22             dp[i][j]=dp[i-1][j];//不放砝码 
23             if(j+a[i]<=m)//放左边 
24             {
25                 dp[i][j]|=dp[i-1][j+a[i]];//或运算,两者其中一个是1这个结果就是1 
26             }
27             dp[i][j]|=dp[i-1][abs(j-a[i])];//放右边 
28         }
29     }
30     for(register int i=1;i<=m;i++)//进行统计 
31     {
32         if(dp[n][i])
33         ans++; 
34     }
35     cout<<ans<<endl;
36     return 0;
37 }

 

posted @ 2022-03-20 15:37  江上舟摇  阅读(347)  评论(0编辑  收藏  举报