我在Codechef上做了这个问题 http://www.codechef.com/PRVG2015/problems/PRVG154/
问题的总结是Alex从左上角开始,希望最大化总分,而Bob希望通过减去他的方式中的元素来最小化总分。 它们交替移动,并且它们只能选择前面选定元素的右侧或底部的元素。 在形成表时,可以看出if(i + j)%2 == 0那么该元素只能被Alex选中,否则,它只能被Bob选中。 因此,对于(i + j)%2 == 1,我们将A [i] [j]更改为-A [i] [j],以便稍后,我们只需添加元素,最小化或最大化,具体取决于指数。
我见过的所有解决方案似乎都是自上而下创建DP [n] [m]表,从右下角到左上角(逆序)(即从dp [n-1]开始) [m-1]到dp [0] [0])。为什么这样做? 我也试过从左上角到右下角,但它没有给出正确的解决方案,尽管逻辑看起来很好。
#include <bits/stdc++.h>
using namespace std;
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int t, n, m, A[500][500],i,j;
int dp[500][500];
cin>>t;
while(t--)
{
cin>>m>>n;
for(i=0;i<m;i++)
for(j=0;j<n;j++)
cin>>A[i][j];
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
{
if((i+j)%2 == 1)
A[i][j] = -1 * A[i][j];
}
}
dp[0][0] = A[0][0];
for(i=1;i<m;i++)
dp[i][0] = dp[i-1][0] + A[i][0];
for(j=1;j<n;j++)
dp[0][j] = dp[0][j-1] + A[0][j];
for(i=1;i<m;i++)
{
for(j=1;j<n;j++)
{
if((i+j)%2 == 0)
{
dp[i][j] = max(dp[i-1][j],dp[i][j-1]) + A[i][j];
}
else
{
dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + A[i][j];
}
}
}
cout<<dp[m-1][n-1]<<"\n";
}
return 0;
}