您的位置:首页 > 其它

hdu2845_Beans

2011-08-23 00:32 120 查看
http://acm.hdu.edu.cn/showproblem.php?pid=2845



把每一行单独出来,如果取了x[i],那么x[i-1]和x[i+1]都不可以取。求这样应该如何取数使所取的数的总和最大?

对于每个数,有取和不取两个状态:

b[i][0] = max(b[i-1][0], b[i-1][1]); //x[i] 不取

b[i][1] = b[i-1][0] + c[i]; //x[i] 取

取 b[i][0] 和 b[i][1] 中的较大值,作为到 x[i] 这里做出的决策最多能得到的总和。

对每一行的处理得到的u[i]表示这一行所能取得的最大总和。由于某一行的某个数的取舍影响的是上下两行一整行的取舍,而不是上下两行某个具体位置的取舍,所以可以直接把第一次dp处理得到的每一行的最大总和合起来看做是一整行求最大总和,然后再进行一次同样的dp处理,得到整个矩阵的最大总和。

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int N = 200000 + 10;
int f
[2], v
[2], u
, a
;

int init(int b[][2], int c[], int n)
{
int maxnum = 0;
for (int i = 1; i <= n; i++)
{
b[i][0] = max(b[i-1][0], b[i-1][1]);
b[i][1] = b[i-1][0] + c[i];
int temp = max(b[i][0], b[i][1]);
maxnum = maxnum > temp ? maxnum : temp;
}
return maxnum;
}

int main()
{
int n, m;
while (scanf("%d%d", &m, &n) != EOF)
{
memset(f, 0, sizeof(f));
memset(v, 0, sizeof(v));
for (int i = 1; i <= m; i++)
{
for (int j = 1; j <= n; j++)
scanf("%d", &a[j]);
u[i] = init(v, a, n);
}
printf("%d\n", init(f, u, m));
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: