1. 程式人生 > >牛客-牛客練習賽21-B 黑妹的遊戲II

牛客-牛客練習賽21-B 黑妹的遊戲II

連結:https://www.nowcoder.com/acm/contest/130/B
來源:牛客網

時間限制:C/C++ 1秒,其他語言2秒
空間限制:C/C++ 131072K,其他語言262144K
64bit IO Format: %lld
題目描述 
黑妹和黑弟又聚在一起玩遊戲了,這次他們選擇在一個n*m的棋盤上玩遊戲,棋盤上的每個方格都有一個非負的分數,
遊戲從左上角開始右下角結束,雙方交替的選擇一個方格並獲得方格上相應的分數,一方選擇的方格必須在上一步另一方選擇的方格
的右邊或者下面,黑妹先開始。現在黑妹想知道,如果雙方都採取最優策略(最優策略是指雙方都希望最終自己的總分數減去對方的總分數最大),她的總分數減去黑弟的總分數會是多少?

輸入描述:
第一行一個整數T表示資料的組數。(1 ≤ T ≤ 20)
對於每組資料:
第一行兩個整數n,m表示棋盤的規格。(1 ≤ n, m ≤ 500)
接下來n行每行m個整數aij表示方格對應的分數。(0<=aij<=10000)

輸出描述:
對於每組資料輸出一行表示答案。

示例1
輸入

2 2 
1 3 
4 5
輸出

2

思路:這麼簡單的動態規劃竟然沒做出來ヽ(#`Д´)ノ,想死。。 

dp[i][j]:表示從a[i][j]到a[n][m]的最佳走法的分數,由於A,B都是最優策略,因此 dp[i][j]=a[i][j]-max(dp[i][j+1],dp[i+1][j])

對於a[i][j]到a[i][j+1]或a[i+1][j],最優策略是走到最大的那個去max(dp[i][j+1],dp[i+1][j]),因此要由終點推至起點,所以最終dp[1][1]就是答案

Code:

#include<iostream>
using namespace std;

const int MAX_N=505;
const int MAX_M=505;
int n,m,T;
int a[MAX_N][MAX_M];

int main()
{
	ios::sync_with_stdio(false);
	cin>>T;
	while(T--){
		cin>>n>>m;
		for(int i=1;i<=n;++i)
			for(int j=1;j<=m;++j)
				cin>>a[i][j];
		for(int i=n;i>=1;--i)
			for(int j=m;j>=1;--j)
				if(i!=n&&j!=m)	a[i][j]-=max(a[i][j+1],a[i+1][j]);
				else	if(i!=n&&j==m)	a[i][j]-=a[i+1][j];
				else	if(i==n&&j!=m)	a[i][j]-=a[i][j+1];
		cout<<a[1][1]<<endl;
	}
	
	return 0;
}