HDU5234 Happy birthday

原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=5234

Happy birthday

Problem Description

Today is Gorwin’s birthday. So her mother want to realize her a wish. Gorwin says that she wants to eat many cakes. Thus, her mother takes her to a cake garden.

The garden is splited into n* m grids. In each grids, there is a cake. The weight of cake in the i-th row j-th column is wij kilos, Gorwin starts from the top-left(1,1) grid of the garden and walk to the bottom-right(n,m) grid. In each step Gorwin can go to right or down, i.e when Gorwin stands in (i,j), then she can go to (i+1,j) or (i,j+1) (However, she can not go out of the garden).

When Gorwin reachs a grid, she can eat up the cake in that grid or just leave it alone. However she can’t eat part of the cake. But Gorwin’s belly is not very large, so she can eat at most K kilos cake. Now, Gorwin has stood in the top-left grid and look at the map of the garden, she want to find a route which can lead her to eat most cake. But the map is so complicated. So she wants you to help her.

Input

Multiple test cases (about 15), every case gives n, m, K in a single line.

In the next n lines, the i-th line contains m integers wi1,wi2,wi3,⋯wim which describes the weight of cakes in the i-th row

Please process to the end of file.

[Technical Specification]

All inputs are integers.

1<=n,m,K<=100

1<=wij<=100

Output

For each case, output an integer in an single line indicates the maximum weight of cake Gorwin can eat.

Sample Input

1 1 2
3
2 3 100
1 2 3
4 5 6

Sample Output

0
16

Hint

In the first case, Gorwin can’t eat part of cake, so she can’t eat any cake.

In the second case, Gorwin walks though below route (1,1)->(2,1)->(2,2)->(2,3). When she passes a grid, she eats up the cake in that grid. Thus the total amount cake she eats is 1+4+5+6=16.

题解

做了那么多dp,发现根据数据范围确定dp姿势是非常科学的。。。

那么,这道题的数据范围是100,多半需要用 O ( n 3 ) O(n^3) O(n3)dp,我们再考虑一下题目本身:

我们可以将每个格子看做一个背包,背包的权值为格子里的蛋糕重量。我们先考虑这样一个二维的背包,dp[i][j]可以从上面和左边的点转移过来,如过加上当前点的权值大于上限,那么不吃,反之就吃。但这样实际上是一个贪心策略,很可能无法达到最优解。

但根据数据我们推算出的复杂度明明是 O ( n 3 ) O(n^3) O(n3)啊,所以我们可以再加一维,布尔数组dp[i][j][k]表示在点(i,j)我们可以吃到k千克蛋糕,我们可以这样转移状态:

如果我们吃了这个点的蛋糕,就可以如此转化:

$dp[i][j][k]=max(dp[i][j][k],dp[i-1][j][k-val[i][j]]);$ $dp[i][j][k]=max(dp[i][j][k],dp[i][j-1][k-val[i][j]]);$
表示我们可以从上面和左边没有吃这个点蛋糕的状态$(k-val[i][j])$吃掉这个点的蛋糕从而变成$k$。

如果没有吃这个点的蛋糕,显然有:

$dp[i][j][k]=max(dp[i][j][k],dp[i-1][j][k]);$ $dp[i][j][k]=max(dp[i][j][k],dp[i][j-1][k]);$
记得初始化。
代码
#include<bits/stdc++.h>
using namespace std;
const int M=105;
int n,m,p,val[M][M];
bool dp[M][M][M];
void in()
{
	memset(dp,0,sizeof(dp));
	for(int i=1;i<=n;++i)
	for(int j=1;j<=m;++j)
	scanf("%d",&val[i][j]),dp[i][j][0]=1;
}
void ac()
{
	for(int i=1;i<=m;++i)
	dp[0][i][0]=1;
	for(int i=1;i<=n;++i)
	dp[i][0][0]=1;
	for(int i=1;i<=n;++i)
	for(int j=1;j<=m;++j)
	{
		for(int k=val[i][j];k<=p;++k)
		{
			dp[i][j][k]=max(dp[i][j][k],dp[i-1][j][k-val[i][j]]);
			dp[i][j][k]=max(dp[i][j][k],dp[i][j-1][k-val[i][j]]);
		}
		for(int k=1;k<=p;++k)
		{
			dp[i][j][k]=max(dp[i][j][k],dp[i-1][j][k]);
			dp[i][j][k]=max(dp[i][j][k],dp[i][j-1][k]);
		}
	}
	for(int i=p;i>=0;--i)
	if(dp[n][m][i])
	{
		printf("%d\n",i);
		return;
	}
}
int main()
{
	while(scanf("%d%d%d",&n,&m,&p)!=EOF)
	in(),ac();
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ShadyPi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值