1. 程式人生 > >P1005 矩陣取數遊戲

P1005 矩陣取數遊戲

main eof std void def 答案 typedef set 輸入輸出

題目描述

帥帥經常跟同學玩一個矩陣取數遊戲:對於一個給定的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: 復制
2 3
1 2 3
3 4 2
輸出樣例#1: 復制
82
#include<bits/stdc++.h>
using namespace std;
#define maxn 10000
typedef long long ll;
#define inf 0x3f3f3f3f

__int128 dp[
85][85]; __int128 f[85]; int a[100][100]; int n,m; __int128 ans=0; __int128 p[100]; void _print(__int128 x) { if(!x) { puts("0"); return; } if(x > 9) _print(x/10); putchar(x%10 + 0); } void print(__int128 x) { if(x < 0) { x = -x; putchar(-); } _print(x); }
int main() { cin>>n>>m; p[0]=1; for(int i=1; i<=m; i++) p[i]=p[i-1]*2; for(int i=1; i<=n; i++) for(int j=1; j<=m; j++) cin>>a[i][j]; for(int k=1; k<=n; k++) { memset(dp,0,sizeof(dp)); for(int i=0; i<=m; i++) for(int j=0; j<=m-i; j++) { if(i>=1) dp[i][j]=max(dp[i][j],dp[i-1][j]+a[k][i]*p[i+j]); if(j>=1) dp[i][j]=max(dp[i][j],dp[i][j-1]+a[k][m-j+1]*p[i+j]); f[k]=max(f[k],dp[i][j]); } ans+=f[k]; } print(ans); return 0; }

P1005 矩陣取數遊戲