现在的位置: 首页 > 综合 > 正文

UVA 10913 Walking on a Grid

2013年08月16日 ⁄ 综合 ⁄ 共 1250字 ⁄ 字号 评论关闭

    设d[i][j][k]为走到(i,j)经过k个负数的收益,负无穷表示无法达到这个状态。由于只能向下、左、右且不能走回头路,于是按层DP就好了。注意用long long。

//10913 	Walking on a Grid 	Accepted 	C++ 	0.032 	2012-12-10 13:29:24
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = 75+5, MAXK = 5+5;
const long long INF = 1LL<<60;
int N, K, g[MAXN][MAXN], cnt[MAXN][MAXN];
long long sum[MAXN][MAXN], d[MAXN][MAXN][MAXK];
int main()
{
	for (int cas = 1; scanf("%d%d", &N, &K); cas++)
	{
		if (!N && !K)
			break;
		for (int i = 1; i <= N; i++)
			for (int j = 1; j <= N; j++)
			{
				scanf("%d", &g[i][j]);
				sum[i][j] = sum[i][j-1]+g[i][j];
				cnt[i][j] = cnt[i][j-1]+(g[i][j] < 0 ? 1 : 0);
			}
		for (int i = 1; i <= N; i++)
			for (int j = 1; j <= N; j++)
				fill(d[i][j], d[i][j]+K+1, -INF);
		for (int j = 1; j <= N && cnt[1][j] <= K; j++)
			d[1][j][cnt[1][j]] = sum[1][j];
		for (int i = 2; i < N; i++)
			for (int j = 1; j <= N; j++)
				for (int p = 1; p <= N; p++)
				{
					int s = (p < j ? sum[i][j]-sum[i][p-1] : sum[i][p]-sum[i][j-1]);
					int c = (p < j ? cnt[i][j]-cnt[i][p-1] : cnt[i][p]-cnt[i][j-1]);
					for (int k = K; k >= c; k--)
						if (d[i-1][p][k-c] > -INF)
							d[i][j][k] = max(d[i][j][k], d[i-1][p][k-c]+s);
				}
		for (int p = 1; p <= N; p++)
		{
			int s = sum[N][N]-sum[N][p-1];
			int c = cnt[N][N]-cnt[N][p-1];
			for (int k = K; k >= c; k--)
				if (d[N-1][p][k-c] > -INF)
					d[N][N][k] = max(d[N][N][k], d[N-1][p][k-c]+s);
		}
		long long ans = -INF;
		for (int k = 0; k <= K; k++)
			ans = max(ans, d[N][N][k]);
		if (ans > -INF)
			printf("Case %d: %lld\n", cas, ans);
		else
			printf("Case %d: impossible\n", cas);
	}
	return 0;
}

抱歉!评论已关闭.