1. 程式人生 > 其它 >藍橋杯試題 歷屆真題 砝碼稱重【第十二屆】【省賽】【B組】

藍橋杯試題 歷屆真題 砝碼稱重【第十二屆】【省賽】【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 }