矩阵取数游戏
矩阵取数游戏
https://ac.nowcoder.com/acm/problem/16645
题目大意:
给定一个n*m的矩阵,每次从每行最右或最左端取一个数,每取走一个数会有一个得分,求最大得分。
思路:
根据题目可知,取数时每行互不影响,所以可以将其分开一行一行的分析,那么问题就转化成求每行最大得分和,对此我们可以用区间dp求解,
设dp[i][j]为i到j区间内最大得分he
推导可得转移方程:dp[i][j]=max(f[i-1][j]+a[i-1]p[k],f[i][j+1]+a[j+1]p[k]);
AC代码:
#include<stdio.h>
#include<string.h>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;
typedef __int128 ll;
int a[110][110];
ll dp[110][110];
ll po[85];
void init(){
po[1]=2;
for(int i=2;i<=80;i++)po[i]=po[i-1]*2;
}
inline void write(__int128 x)
{
if(x<0)
{
putchar('-');
x=-x;
}
if(x>9)
write(x/10);
putchar(x%10+'0');
}
int main(){
init();
int n,m;
ll sum=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&a[i][j]);
for(int coun=1;coun<=n;coun++){
memset(dp,0,sizeof(dp));
for(int d=1;d<=m;d++)
for(int i=1,j=d;j<=m;j++,i++)
dp[i][j]=max(dp[i+1][j]+a[coun][i]*po[m-d+1],dp[i][j-1]+a[coun][j]*po[m-d+1]);
sum+=dp[1][m];
}
write(sum);
return 0;
}
