帥帥經常跟同學玩乙個矩陣取數遊戲:對於乙個給定的n×mn \times mn×m的矩陣,矩陣中的每個元素ai,ja_ai,j均為非負整數。遊戲規則如下:
每次取數時須從每行各取走乙個元素,共nnn個。經過mmm次後取完矩陣內所有元素;
每次取走的各個元素只能是該元素所在行的行首或行尾;
每次取數都有乙個得分值,為每行取數的得分之和,每行取數的得分 = 被取走的元素值×2i\times 2^i×2i,其中iii表示第iii次取數(從111開始編號);
遊戲結束總得分為mmm次取數得分之和。
帥帥想請你幫忙寫乙個程式,對於任意矩陣,可以求出取數後的最大得分。
輸入格式:
輸入檔案包括n+1n+1n+1行:
第111行為兩個用空格隔開的整數nnn和mmm。
第2∽n+12\backsim n+12∽n+1行為n×mn \times mn×m矩陣,其中每行有mmm個用單個空格隔開的非負整數。
輸出格式:
輸出檔案僅包含111行,為乙個整數,即輸入矩陣取數後的最大得分。
輸入樣例#1:複製
2 3輸出樣例#1:複製1 2 3
3 4 2
82noip 2007 提高第三題
資料範圍:
60%的資料滿足:1≤n,m≤301\le n, m \le 301≤n,m≤30,答案不超過101610^1016
100%的資料滿足:1≤n,m≤801\le n, m \le 801≤n,m≤80,0≤ai,j≤10000 \le a_ \le 10000≤ai,j≤1000
高精加dp
可以一行一行地dp
dp[i][j]表示i到j的最優值
轉移時從dp[i+1][j]或dp[i][j-1]轉移過來
注意乘2
#includeusingview codenamespace
std;
const
int maxn = 85
;const
intbase =1e4;
const
int power = 4
;int
n,m,mp[maxn];
struct
big big& operator = (int
sum)
a[0]=len;
return *this
; }
void
print()
printf("\n
");}
}jc[maxn],dp[maxn][maxn],ans;
big
operator *(const
int sum,const big&q)
while(c.a[c.a[0]+1]) c.a[0]++;
returnc;}
big
operator *(const big& p,const big&q)
while(c.a[c.a[0]+1]) c.a[0]++;
returnc;}
void
getjc()
big max(
const big& p,const big&q)
returnp;}
big
operator +(const big& p,const big&q)
while(c.a[c.a[0]+1]) c.a[0]++;
returnc;}
intmain()
ans=ans+dp[1
][m];
}ans.print();
return0;
}
P1005 矩陣取數遊戲
p1005 矩陣取數遊戲 區間dp,憨貪心可以過兩個點,f l r 表示l,r這一段都選完的取得的最大得分 f l r max f 1 l r a l f l r 1 a r 2 越靠中間,乘的2越多,列舉區間長度,和左右端點 答案是f 1 m 1 include2 include3 include...
P1005 矩陣取數
看完題可能第一時間並沒有清晰的思路。讓我們一步一步的來考慮這道題目。題目中描述操作為每次從所有的行中選取,這樣做有些麻煩。仔細思考一下可以發現行與行之間互不干涉,所以我們可以對每行操作到底,最後統計答案。每行怎麼選取當然難不倒聰明的oier了,設f i j 表示某行從第i位到第j位的最優答案。轉移如...
洛谷p1005矩陣取數遊戲
原題 2 80超int,需要高精度計算,也可以int128.行和行之間沒有聯絡,所以只要單獨求每一行之後取和即可,dp過程中i,j分別表示左端點和右端點。include define lll int128 void print lll x int n,m lll ans 0 int a 100 ll...