乙個動態規劃的經典問題,以下標代表數值

2021-08-23 12:04:14 字數 1448 閱讀 4662

本題是在牛客網上的討論區發現的位元組跳動的筆試題,感覺很有意思。原作者寫的思路我看了很久才看明白。在這裡記錄一下個人理解。

原題意思大概如下:

a和b兩個人在一組牌中各自選取幾張。每張牌上有兩個數字,乙個代表得到該牌後的個人分,另乙個代表團體分。要求最後a,b兩人個人得分相同,團體得分最大。

輸入:

第一行乙個整數,n代表牌的數量,

接下來n行,每行兩個數字。

輸出: 最大團體得分

示例: 輸入:

51 1

1 23 4

5 62 3

輸出:13

無效思路:

最優化問題通常都是使用動態規劃去解。我剛開始的想法是對每一張牌都有兩種情況:選,不選。

不選的情況下opt(i) = opt(i-1),選了的話就要判斷選這張牌的情況下剩餘的牌的最優情況。是有後效性的,十分複雜。這讓我一度懷疑這題能不能使用動態規劃。在後面的學習中才認識,對於同一問題既可以存在有後效性的問題定義,也可以有無後效性的問題定義。要使用動態規劃解題,就得找出問題的無後效性定義,從而寫出其狀態轉移方程。

正確思路:

使用動態規劃是毫無疑問的了。難就難在對該問題給出乙個無後效性的定義。

記x(a), x(b)分別為玩家a,b的個人得分,sumx為所有卡片的個人得分之和,sumy為所有卡片的團體得分之和。

a和b的個人得分之差為x(a) - x(b),當x(a) **如下:

#include 

#include

#include

#include

#include

#include

using

namespace

std;

int main()

}cout

<< f[cur][sumx] << endl;

}}

再總結一下動態規劃:

找出無後效性定義,寫出狀態轉移方程,根據狀態轉移方程求解。本題中還應注意到一點:以陣列下標表示了a,b之間的個人得分關係。不同陣列代表了處理的不同卡片時的所有得分關係的狀態。

每個階段的最優狀態可以從之前某個階段的某個或某些狀態直接得到而不管之前這個狀態是如何得到的。

每個階段的最優狀態可以從之前某個階段的某個或某些狀態直接得到
這個性質叫做最優子結構;

而不管之前這個狀態是如何得到的
這個性質叫做無後效性。

再廢話兩句:

一開始的無效思路,對於i-1選或者不選,會影響到選擇i後還能不能保證差值為0。因此是存在後效性。而有效方案則將個人得分差值情況與團體得分情況分開了,其計算了所有差值情況的團體分,得到整體最優再選擇了差值0的最優解。

動態規劃的兩個經典問題

weight 原始物品陣列,values 為其所對應的價值,n 表示物品的個數,w 表示揹包所能承受的最大重量 public void knapsack3 int weight,int values,int n,int w states 0 0 0 if weight 0 w for int i 1...

C 處理乙個動態規劃的問題

要求是遞迴,動態規劃,想了想這種方法也是最簡單的 所謂動態規劃 把多階段過程轉化為一系列單階段問題,利用各階段之間的關係,逐個求解。動態規劃演算法通常用於求解具有某種最優性質的問題。在這類問題中,可能會有許多可行解。每乙個解都對應於乙個值,我們希望找到具有最優值的解。動態規劃演算法與分治法類似,其基...

乙個線代的問題

在 kaoyan a u ready?的大作中提到 是99年試題 a是乙個二階方陣,試證 如果有矩陣b使得ab ba a,則a 2 0 發信人 researchmonk 蟄伏中.信區 kaoyan 標 題 re cs 乙個線代的問題 發信站 北大未名站 2003年01月05日09 47 01 星期天...