POJ 1837 Balance [動態規劃——完全揹包]

題幹

Description

Gigel has a strange “balance” and he wants to poise it. Actually, the device is different from any other ordinary balance.
It orders two arms of negligible weight and each arm’s length is 15. Some hooks are attached to these arms and Gigel wants to hang up some weights from his collection of G weights (1 <= G <= 20) knowing that these weights have distinct values in the range 1..25. Gigel may droop any weight of any hook but he is forced to use all the weights.
Finally, Gigel managed to balance the device using the experience he gained at the National Olympiad in Informatics. Now he would like to know in how many ways the device can be balanced.

Knowing the repartition of the hooks and the set of the weights write a program that calculates the number of possibilities to balance the device.
It is guaranteed that will exist at least one solution for each test case at the evaluation.
Input

The input has the following structure:
• the first line contains the number C (2 <= C <= 20) and the number G (2 <= G <= 20);
• the next line contains C integer numbers (these numbers are also distinct and sorted in ascending order) in the range -15..15 representing the repartition of the hooks; each number represents the position relative to the center of the balance on the X axis (when no weights are attached the device is balanced and lined up to the X axis; the absolute value of the distances represents the distance between the hook and the balance center and the sign of the numbers determines the arm of the balance to which the hook is attached: ‘-’ for the left arm and ‘+’ for the right arm);
• on the next line there are G natural, distinct and sorted in ascending order numbers in the range 1..25 representing the weights’ values.
Output

The output contains the number M representing the number of possibilities to poise the balance.
Sample Input

2 4
-2 3
3 4 5 8
Sample Output

2

題解

/**
*這個題目,起初只考慮到了用平衡量結合動態規劃做,但是還是沒有想明白,
*包括dp數組初始化什麼的,後來轉移方程搞出來了,總結有以下幾點:
*1,不可禁錮思維,每個題目都有他自己的特殊之處,特殊情況特殊討論
*2,要把整個程序運行的過程在腦子裏面過一遍,從初始化到出結果都要在腦子裏面過一遍
*想清楚了纔可以
*3,做的比較好的就是,在紙上用動態轉移方程演算了一下樣例,這讓我避免了重複修改代碼
*4,應該看清題意:#所以砝碼都要用上#每個掛鉤可以掛無限個#
*/
#include<cstdio>
const int N = 16000;//G*砝碼最大重量*槓杆最大臂長=7500,所以範圍是-7500~7500,
//爲了計算方便,統一用shiftint)偏移到0~15000
const int M = 25;
int shift(int a){
  return a+7500;
}
int dp[25][N];
int main(){
  int C,G,cs[M],gs[M];
  while(~scanf("%d%d",&C,&G)){
    for(int i=1;i<=C;i++)scanf("%d",&cs[i]);
    for(int i=1;i<=G;i++)scanf("%d",&gs[i]);
    for(int i=-7500;i<=7500;i++)for(int j=0;j<M;j++){
       dp[j][shift(i)] = 0;//初始化
    }
    for(int k=1;k<=C;k++){
       dp[1][shift(cs[k]*gs[1])] = 1;//只掛第一個砝碼,各種掛法下的情況
    }
    for(int i=2;i<=G;i++){
       for(int j=-7500;j<=7500;j++){
           for(int k=1;k<=C&&shift(j-cs[k]*gs[i])>=0;k++){
              dp[i][shift(j)] += dp[i-1][shift(j-cs[k]*gs[i])];//轉移方程
              //dp[i][j]代表前i個砝碼在平衡量爲j的情況的下的方案數,要記得用+=,
              //因爲可能之前就有結果可以用了,
           }
       }
    }
    printf("%d\n",dp[G][shift(0)]);
  }
}
發佈了40 篇原創文章 · 獲贊 0 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章