P1282 多公尺諾骨牌

2021-09-07 14:42:43 字數 2398 閱讀 6003

多公尺諾骨牌有上下2個方塊組成,每個方塊中有1~6個點。現有排成行的

上方塊中點數之和記為s1,下方塊中點數之和記為s2,它們的差為|s1-s2|。例如在圖8-1中,s1=6+1+1+1=9,s2=1+5+3+2=11,|s1-s2|=2。每個多公尺諾骨牌可以旋轉180°,使得上下兩個方塊互換位置。 程式設計用最少的旋轉次數使多公尺諾骨牌上下2行點數之差達到最小。

對於圖中的例子,只要將最後乙個多公尺諾骨牌旋轉180°,可使上下2行點數之差為0。

輸入格式:

輸入檔案的第一行是乙個正整數n(1≤n≤1000),表示多公尺諾骨牌數。接下來的n行表示n個多公尺諾骨牌的點數。每行有兩個用空格隔開的正整數,表示多公尺諾骨牌上下方塊中的點數a和b,且1≤a,b≤6。

輸出格式:

輸出檔案僅一行,包含乙個整數。表示求得的最小旋轉次數。

輸入樣例#1:

4

6 11 5

1 31 2

輸出樣例#1:

1
參照洛谷題解

這種題目方法應該都是大同小異。

考慮乙個揹包,

顯然如果我們直接設dp[i]表示前i個使差值最小所需的最少翻轉次數,是具有後效性的。

所以我們將直接求最值,改為求某個值是否可行,這種求最值轉變為求可行性的思想是非常實用的。

我們設dp[i][j]表示前i個數字通過某種旋轉方式使得差值為j(不帶絕對值)所需的最少翻轉次數,那麼我們最終dp結束後只需找到絕對值最小的非正無窮的dp值,輸出即可。

考慮具體的dp過程(個人採用刷表法,填表法方程類似):

dp[i+1][j+b[i]-a[i]]=min(dp[i][j]+1)//翻轉

dp[i+1][j+a[i]-b[i]]=min(dp[i][j])//不翻轉

初始化:dp[1][b[1]-a[1]]=1,dp[1][a[1]-b[1]]=0.

對於討論**現的極端資料,一定要把初始化方程按順序(即=1的在上面,=0的在下面,這樣的話如果a[1]=b[1]那麼0就會直接覆蓋上面的1)寫就行了。

又因為cpp語言中陣列沒有負的下標,所以還要陣列平移一下。p黨可以偷笑了。

至於揹包不能加滾動陣列的說法純屬che,dan,只是一些偽dalao的會而已。

滾動陣列的方法具體可見**。

1 #include2 #include3 #include4 #include5

using

namespace

std;

6 templatevoid chkmin(t &a,t b)

7const

int inf=0x3f3f3f3f;8

const

int n=1010;9

int dp[2][20*n],a[n],b[n];//

陣列使勁開,我就是開小了,先是9,然後73,然後91,最後ac = =

10int

n;11

intmain()

18 memset(dp,0x3f,sizeof

(dp));

19 dp[1][2*tot-a[1]+b[1]]=1

;20 dp[1][2*tot+a[1]-b[1]]=0;21

for (int i=1;i)29}

30for (int i=2*tot;i<=3*tot;i++)

31if (dp[n&1][i]!=inf || dp[n&1][4*tot-i]!=inf)

35return0;

36 }

遇見這種直接揹包。

揹包的本質是什麼???

是每乙個物品或動作對所有當前狀態的更新。

本題就是如此,翻一次就把原來的加的差值顛倒。

並且,本題強制必須要用每乙個動作,所以就必須(即+a-b或+b-a)從前面乙個狀態+改變量去更新

因為改變量有正有負,所以不好降一維,

其實可以用滾動陣列,但為了偷懶 (^_^),就用了二維的 (^_^)

小心負數下標陣列越界!!!!!

1 #include2 #include3 #include4 #include5

using

namespace

std;

6int a[1005],b[1005];7

int f[1005][12001];8

const

int n=5000;9

intmain()

1024

//核心**結束

25for(i=0;i<=5000;i++)

2633}34

return0;

35 }

P1282 多公尺諾骨牌

多公尺諾骨牌有上下2個方塊組成,每個方塊中有1 6個點。現有排成行的 上方塊中點數之和記為s1,下方塊中點數之和記為s2,它們的差為 s1 s2 例如在圖8 1中,s1 6 1 1 1 9,s2 1 5 3 2 11,s1 s2 2。每個多公尺諾骨牌可以旋轉180 使得上下兩個方塊互換位置。程式設計...

P1282 多公尺諾骨牌

p1282多公尺諾骨牌 這個題其實挺水的,主要是對於這個狀態的理解 1.dp i j dp i j a i b i 2.dp i j dp i j b i a i 1 兩個狀態取乙個min就行了。為什麼這樣的轉移是合理的呢。我們規定上面一半的點數為a i 下面一半的點數為b i 那麼首先我們看 1....

P1282 多公尺諾骨牌

problem 此題是一道01揹包。關於01 揹包 我不想講了 my blog 這道題是一道基礎的01揹包問題 設f i j k表示前i張牌構成分值j的最小次數k 設 dis a i b i 不反轉 f i j dis n min f i j dis n f i 1 j n 反轉 f i j dis...