題目描述
帥帥經常跟同學玩乙個矩陣取數遊戲:對於乙個給定的n*m的矩陣,矩陣中的每個元素a[i,j] 均為非負整數。遊戲規則如下:
每次取數時須從每行各取走乙個元素,共n個。m次後取完矩陣所有元素;
每次取走的各個元素只能是該元素所在行的行首或行尾;
每次取數都有乙個得分值,為每行取數的得分之和,每行取數的得分 = 被取走的元素值*2^i,其中i表示第i次取數(從1開始編號);
遊戲結束總得分為m次取數得分之和。帥帥想請你幫忙寫乙個程式,對於任意矩陣,可以求出取數後的最大得分。
輸入
輸入檔案game.in包括n+1行:
第1行為兩個用空格隔開的整數n和m。
第2~n+1行為n*m矩陣,其中每行有m個用單個空格隔開的非負整數。
輸出輸出檔案game.out僅包含1行,為乙個整數,即輸入矩陣取數後的最大得分。
樣例輸入
sample input1:
2 31 2 3
3 4 2
sample input2:
1 44 5 0 5
sample input3:
2 10
96 56 54 46 86 12 23 88 80 43
16 95 18 29 30 53 88 83 64 67
樣例輸出
sample output1:
【輸入輸出樣例1解釋】
第1次:第1行取行首元素,第2行取行尾元素,本次得分為1*21+2*21=6
第2次:兩行均取行首元素,本次得分為2*22+3*22=20
第3次:得分為3*23+4*23=56。總得分為6+20+56=82
sample output2:
sample output3:
資料範圍限制
【限制】
60%的資料滿足:1<=n, m<=30, 答案不超過10^16
100%的資料滿足:1<=n, m<=80, 0<=a[i,j]<=1000
思路:
dp可以發現每一行可以單獨處理,答案就是每一行獲得的最大分數的和。
要高精度,注意常數優化。
#include#pragma gcc optimize(3)
#define open(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout);
#define n 100
#define ll long long
using namespace std;
ll base=1000;
ll work(ll b)
return ans;
}struct bignum
void init()
bool operator < (const bignum &y) const
while(b)
return *this;
} bignum operator +(const bignum b)
if(c.num[tmp+1]>0)c.len=tmp+1;else c.len=tmp;
return c;
}bignum operator *(const ll a)
if(b.num[b.len+3])b.len+=3;else if(b.num[b.len+2])b.len+=2;else if(b.num[b.len+1])b.len+=1;
return b;
} void print() }
}int main()
ans.print();
}
NOIP2007提高組 矩陣取數遊戲
本題dp 高精度即可。首先我們可以發現它的貢獻只與行有關係,於是就分成n行,每行都做dp,然後將max加起來即可。ps 用高精度實現 上標 include include include define mo 100000 define ll long long using namespace std...
NOIP2007提高組 矩陣取數遊戲
本題dp 高精度即可。首先我們可以發現它的貢獻只與行有關係,於是就分成n行,每行都做dp,然後將max加起來即可。ps 用高精度實現 上標 include include include define mo 100000 define ll long long using namespace std...
NOIp2007提高組 矩陣取數遊戲
oj題號 洛谷1005 思路 動態規劃。不難發現每行能夠取得的最大值僅與當前行的資料有關,因此本題可以對每行的資料分別dp,最後求和。設 f 表示左邊取 i 個 右邊取 j 個的最大值,則dp方程為 f max f a 2 f a 2 然而資料規模較大,使用 int 只有40分,用 unsigned...