洛谷1005 矩陣取數遊戲(dp 高精)

2021-07-05 07:18:58 字數 1448 閱讀 7541

題目描述 description

帥帥經常跟同學玩乙個矩陣取數遊戲:對於乙個給定的n*m的矩陣,矩陣中的每個元素aij均為非負整數。遊戲規則如下:

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

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

3.每次取數都有乙個得分值,為每行取數的得分之和,每行取數的得分 = 被取走的元素值*2^i,其中i表示第i次取數(從1開始編號);

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

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

輸入格式:

輸入檔案game.in包括n+1行:

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

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

資料範圍:

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

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

輸出格式:

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

樣例測試點#1

noip 2007 提高第三題

2 31 2 3

3 4 2

82

#include #include #include #include #include #include #include #include using namespace std;

const int maxn=82;

int ans[maxn],p[maxn],n,m,f[maxn][maxn][32],er[maxn][maxn];

int fpi[maxn],spi[maxn];

int fsum[maxn],ssum[maxn];

inline int get()

inline void mul(int *a,int *b,int x)

while(c[c[0]+1])++c[0],c[c[0]]+=c[c[0]-1]/10,c[c[0]-1]%=10;

for(int i=0;i<=30;++i)a[i]=c[i];

}inline void add(int *q,int *a,int *b)

if(c[c[0]+1])++c[0];

for(int i=0;i<=30;++i)q[i]=c[i];//不知道為什麼要到30(或》)而不是c[ 0 ],掛了乙個點

}inline bool mx(int *a,int *b)

思路:剛開始想的貪心是錯的,本來認為每次取頭尾二者中的最小值,可結果不一定最優。已知最終結果等於每行最大結果的和,想到dp,即f[ i ][ j ]表示從i到j的數最大解=max(f[ i ][ j-1] +a[j]*2^x,f[ i+1 ][ j ]+a[ i ]*2^x);f[ 1 ][ m ]即為該行最大解。再用高精。

洛谷1005 矩陣取數遊戲

傳送門 思路 首先當然是每行單獨處理 再把答案相加 我們發現如果知道還沒有取數的區間長度 就知道現在取了多少個數 也就是說我們可以知道現在要取的數做貢獻要乘的係數 每次取數只能在左右兩端取 所以轉移的時候在這兩種情況中取min即可 記蒐會很方便啊 code 1 include2 include3 i...

洛谷 P1005 矩陣取數遊戲 區間dp

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

洛谷 P1005 矩陣取數遊戲(區間DP)

會發現每一行之間沒有影響,可以做n次區間dp。設dp i j 表示區間 i,j 的取分最大值。如果從小區間向大區間轉移,即 dp i j max dp i 1 j a i dp i j 1 a j 2 這樣 2 i 在轉移的過程中便之間乘上了。ac 無高精 1 include2 include3 i...