動態規劃 取數遊戲 高精度區間DP

2021-09-24 05:47:34 字數 1538 閱讀 2886

【問題描述】

帥帥經常跟同學玩乙個矩陣取數遊戲:對於乙個給定的n*m 的矩陣,矩陣中的每個元素aij均

為非負整數。遊戲規則如下:

1. 每次取數時須從每行各取走乙個元素,共n個。m次後取完矩陣所有元素;

2. 每次取走的各個元素只能是該元素所在行的行首或行尾;

3. 每次取數都有乙個得分值,為每行取數的得分之和,每行取數的得分= 被取走的元素值*2i,

其中i 表示第i 次取數(從1 開始編號);

4. 遊戲結束總得分為m次取數得分之和。

帥帥想請你幫忙寫乙個程式,對於任意矩陣,可以求出取數後的最大得分。

輸入描述 input description

第1行為兩個用空格隔開的整數n和m。

第2~n+1 行為n*m矩陣,其中每行有m個用單個空格隔開的非負整數。

輸出 僅包含1 行,為乙個整數,即輸入矩陣取數後的最大得分。

2 31 2 3

3 4 2

資料範圍及提示 data size & hint

第 1 次:第1 行取行首元素,第2 行取行尾元素,本次得分為1*21+2*21=6

第2 次:兩行均取行首元素,本次得分為2*22+3*22=20

第3 次:得分為3*23+4*23=56。總得分為6+20+56=82

【限制】

60%的資料滿足:1<=n, m<=30, 答案不超過1016

100%的資料滿足:1<=n, m<=80, 0<=aij<=1000

考慮到data[i]*2^n,數字比較大,容易超出longlong容納範圍,因此採用了高精度的寫法。

為了讓**比較簡單,採用分段儲存dp資料,將高16位與低16位分開儲存。

另外就是dp的思路:

將dp[i][j] 定義為,一行中第i個數到第j個數最優取數得分。

狀態轉移方程:dp[i][j] = max(  dp[i+1][j]+data[i]*pow(k) ,  dp[i][j-1]+data[j]*pow(k)  );k表示取數的次數。

邊界:dp[i][i] = data[i]*pow(m);m表示列數

#includeusing namespace std;

typedef long long ll;

ll max=1e15;

struct bn;

bn operator+(const bn a,const bn b)

return c;

}int operator<(const bn a,const bn b)

return c;

}void write(const bn a)

bn max(const bn a,const bn b)

for(j=1;jfor(i=1;i<=m-j;i++)

f[i][i+j]=max(f[i+1][i+j]+pow2(m-j)*a[i],f[i][i+j-1]+pow2(m-j)*a[i+j]);

score=score+f[1][m];

} write(score);

}

1166 矩陣取數遊戲 區間dp 高精度

2007年noip全國聯賽提高組 時間限制 1 s 空間限制 128000 kb 題目等級 gold 題解 問題描述 帥帥經常跟同學玩乙個矩陣取數遊戲 對於乙個給定的n m 的矩陣,矩陣中的每個元素aij均 為非負整數。遊戲規則如下 1.每次取數時須從每行各取走乙個元素,共n個。m次後取完矩陣所有元...

P1005 矩陣取數遊戲 區間dp 高精度

帥帥經常跟同學玩乙個矩陣取數遊戲 對於乙個給定的n times mn m的矩陣,矩陣中的每個元素a ai,j 均為非負整數。遊戲規則如下 每次取數時須從每行各取走乙個元素,共nn個。經過mm次後取完矩陣內所有元素 每次取走的各個元素只能是該元素所在行的行首或行尾 每次取數都有乙個得分值,為每行取數的...

區間DP 矩陣取數遊戲

試題 noip2007 提高組 問題描述 帥帥經常跟同學玩乙個矩陣取數遊戲 對於乙個給定的 n m的矩陣,矩陣中的每個元素 aij均為非負整數。遊戲規則如下 1.每次取數時須從每行各取走乙個元素,共 n個。m次後取完矩陣所有元素 2.每次取走的各個元素只能是該元素所在行的行首或行尾 3.每次取數都有...