此题贪心可解……
提示:
1. 对于一个格子而言 , 其实只有两种方式能够走到他
2. 如果把每一次走当作水流流过的话 , 那么水流最好能够停在左边 , 因为这样的选择空间更大
3. 如果说应该先处理方案数最少的点 , 那么应该是右上角 , 因为要到那个点只有一条路径
代码后详解:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <deque>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <algorithm>
#include <cassert>
using namespace std;
const int maxn = 1100;
int T , n , m;
int g[maxn][maxn];
int f[maxn];
int main(int argc, char *argv[]) {
cin>>T;
while(T--)
{
cin>>n>>m;
memset(f, 0, sizeof(f));
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d" , &g[i][j]);
int res = 0;
for(int i=1;i<=n;i++)
{
int tmp = 0 , req , have , now;
for(int j=m;j>=1;j--)
{
req = max(tmp , g[i][j]);
have = max(f[j] , req);
now = f[j];
f[j] = have - tmp;
tmp = have - now;
}
res += tmp;
}
cout<<res<<endl;
}
return 0;
}
总体思路是从上往下一行行的扫。
tmp
表示如果要满足当前格子的要求 , 左边至少需要流给我多少流量。 我们从右往左计算
tmp
这样对于每一行水流就停在了最佳位置(也就是尽量靠左)。
网上很多DP的递推式和我的很相似 , 但是我不知道其中的联系(网上的做法好高大上啊QAQ)如果有神犇能一语道破 , 请不吝赐教:-)