1. 程式人生 > 其它 >Balance--用動態規劃記錄狀態的非最優解問題

Balance--用動態規劃記錄狀態的非最優解問題

均衡

描述:

吉格爾有一種奇怪的“平衡”,他想保持平衡。實際上,該裝置不同於任何其他普通天平。

它訂購了兩條重量可以忽略不計的手臂,每條手臂的長度為15。一些鉤子連線到這些手臂上,Gigel想掛起他收集的G重量(1<=G<=20)中的一些重量,因為知道這些重量在1範圍內有不同的值。。25.Gigel可以放下任何鉤子的任何重量,但他必須使用所有重量。

最後,Gigel利用在全國資訊學奧林匹克運動會上獲得的經驗,成功地平衡了裝置。現在他想知道該裝置可以通過多少種方式實現平衡。

瞭解掛鉤的重新分配和重量設定,編寫一個程式,計算平衡裝置的可能性數量。

保證在評估時,每個測試用例至少存在一個解決方案。

輸入:

輸入具有以下結構:

•第一行包含數字C(2<=C<=20)和數字G(2<=G<=20);

•下一行包含-15範圍內的C整數(這些數字也不同,並按升序排序)。。15代表吊鉤的重新分配;每個數字代表相對於X軸上天平中心的位置(當未連線砝碼時,裝置平衡並與X軸對齊;距離的絕對值表示吊鉤與平衡中心之間的距離,數字符號確定吊鉤連線的天平臂:“-”表示左臂,“+”表示右臂);

•下一行有G個自然的、不同的、按升序排列的數字,範圍為1。。25表示權重值。

輸出:

輸出包含數字M,代表平衡平衡的可能性數量。

樣例輸入:

2 4

-2 3

3 4 5 8

複製

樣例輸出:

2

大佬的講解部落格:

https://www.cnblogs.com/lyy289065406/archive/2011/07/31/2122629.html

這道題最讓我沒想到的是居然可以在不是求最優解的題目中用動態規劃;

根據大佬的說法好像其使用條件是:

dp思路:

每向天平中方一個重物,天平的狀態就會改變,而這個狀態可以由若干前一狀態獲得。

一開始我也想的是列舉,但算一下就知道會超時;然後我傻了,不知所措;

但看了題解才知道用動態規劃,我就在想為什麼動態規劃就比列舉會快這麼多呢?動態規劃也不是有列舉嗎?

可能是結構不同:列舉可能有時在某一部分相同的地方列舉太多次了;

而動態規劃卻可以儲存重複的地方,精確枚舉出真正要的地方,且只列舉一次;

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 using namespace std;
 6 int hookplace[25],weight[25];
 7 int dp[25][15000];
 8 int main()
 9 {
10     int hooknum,weightnum;
11     cin>>hooknum>>weightnum;
12     for (int i=1;i<=hooknum;i++)
13     {
14         cin>>hookplace[i];
15     }
16     for (int j=1;j<=weightnum;j++)
17     {
18         cin>>weight[j];
19     }
20     memset (dp,0,sizeof (dp));
21     dp[0][7500]=1;
22     for (int i=1;i<=weightnum;i++)
23     {
24         for (int j=1;j<=hooknum;j++)
25         {
26             for (int k=0;k<=15000;k++)
27             {
28                 if (dp[i-1][k]!=0)
29                 {
30                     dp[i][k+weight[i]*hookplace[j]]+=dp[i-1][k];
31                 }
32             }
33         }
34     }
35     cout<<dp[weightnum][7500];
36     return 0;
37 }