POJ1157解题报告

通过这个题目,对自顶向下分析,有了进一步的理解。
题意如下表:

Vases(j)

1

2

3

4

5

Bunches

(i)

1

7

23

-5

-24

16

2

5

21

-4

10

23

3

-21

5

-4

-20

20

1,2,3行代表三束花,1,2,3,4,5列代表这么多列的花瓶,要把三束花放到花瓶中,满足一下几个条件:
  1. 不同的花要出现在不同的列
  2. j1表示1号花放的列,依次。保证j1<j2<j3
  3. 最重要的,要保证三个位置上的数字和最大。
分析这个题目,首先可以得到:
  1. 1号花只能放在1,2,3三个位置,由1,2两个条件可得;
  2. 2号花只能放在2,3,4三个位置;
  3. 3号花只能放在3,4,5三个位置。
上面的发现,对实现算法细节很重要,如果不考虑这些,则必将是WA。下面讨论状态转移方程(我也学得越来越专业了)。首先,假设dp[i][j]表示:第i号花放在第j列的第i个位置。那么dp[i][j]值与那些有关系呢?
  1. 肯定是a[i][j];
  2. d[i - 1][j - 1]
  3. dp[i - 1][j  - 2]
  4. ...
  5. 注意j不能够越界!!!
那么状态转移方程就为:
dp[i][j] = max(dp[i - 1][j - 1] + a[i][j], dp[i - 1][j - 2] + a[i][j], ...)
注意不要越界即可,AC代码如下:
#include 

int a[101][101], dp[101][101];
int f, v;
int main() {
	scanf("%d", &f);
	scanf("%d", &v);
	for (int i = 1; i <= f; ++i)
		for (int j = 1; j <= v; ++j)
			scanf("%d", &a[i][j]);
	for (int i = 1; i <= f; ++i) {
		dp[i][1] = 0;
	}
	for (int i = 1; i <= v; ++i) {
			if (v - i > f - 1)
				dp[1][i] = a[1][i];
			else
				dp[1][i] = 0;
		}
	for (int i = 2; i <= f; ++i) {
		for (int j = i; j <= v - f + i; ++j) {
			dp[i][j] = -1000;
			for (int k = i - 1; k < j; ++k) {
				if (dp[i - 1][k] + a[i][j] > dp[i][j])
					dp[i][j] = dp[i - 1][k] + a[i][j];
			}
		}
	}
	int max = -1000;
	for (int i = v - f + 1; i <= v; ++i) {
		if (dp[f][i] > max) max = dp[f][i];
	}
	printf("%d\n", max);
	return 0;
}

 

posted on 2012-02-05 21:13  sing1ee  阅读(143)  评论(0编辑  收藏  举报