题目:矩阵取数游戏
思路:
每一行单独考虑。
f[lne][i][j]
f
[
l
n
e
]
[
i
]
[
j
]
表示第lne行,
[i,j]
[
i
,
j
]
内的最大价值。
f[lne][i][j]=max(mi[k]∗a[lne][j]+f[lne][i][j−1],mi[k]∗a[lne][i]+f[lne][i+1][j])
f
[
l
n
e
]
[
i
]
[
j
]
=
m
a
x
(
m
i
[
k
]
∗
a
[
l
n
e
]
[
j
]
+
f
[
l
n
e
]
[
i
]
[
j
−
1
]
,
m
i
[
k
]
∗
a
[
l
n
e
]
[
i
]
+
f
[
l
n
e
]
[
i
+
1
]
[
j
]
)
犯规不想写高精度用__int128代替了……
代码:
#include<bits/stdc++.h>
using namespace std;
#define int128 __int128
#define maxn 80
int n,m;
int a[maxn+5][maxn+5];
int128 mi[maxn+5];
int128 f[maxn+5][maxn+5][maxn+5];
void readin() {
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) {
for(int j=1;j<=m;j++) {
scanf("%d",&a[i][j]);
}
}
}
void make2mi() {
mi[0]=1;
for(int i=1;i<=m;i++) {
mi[i]=2*mi[i-1];
}
}
void write(int128 x) {
if(x==0) printf("0");
vector<int> ans;
while(x) {
ans.push_back(x%10);
x/=10;
}
while(ans.size()){
printf("%d",ans[ans.size()-1]);
ans.pop_back();
}
}
int128 dp() {
for(int lne=1;lne<=n;lne++){
for(int i=m;i>=1;i--) {
for(int j=i;j<=m;j++) {
int k=m-j+i;
if(i==j) f[lne][i][j]=mi[k]*a[lne][i];
f[lne][i][j]=max(f[lne][i][j], max(mi[k]*a[lne][j]+f[lne][i][j-1],mi[k]*a[lne][i]+f[lne][i+1][j]) );
}
}
}
int128 ans=0;
for(int i=1;i<=n;i++) ans+=f[i][1][m];
return ans;
}
int main() {
readin();
make2mi();
int128 ans=dp();
write(ans);
return 0;
}