看起来像是二维dp,实际上是两次线性dp。
看了题解之后一次AC。
思路是先求出每一行的最大非连续子序列和,得到一个新的序列。
再求这个新的序列的最大非连续子序列和。
有一个问题是:
为什么要先求每一行的呢?
可以通过下面的情况来说明:
两个点的坐标分别是(1,3),(2,1)
假如先求每一列的最大非连续子序列和,并且(2,1)在第一列中被选中,(1,3)在第三列中被选中。此时符合题意。
得到一个新序列。
但是当对新序列求解的时候,第一列和第三列若同时被选中(有这种可能),则(2,1)(1,3)两个点都被选中。违背了行不能相邻的要求。
附AC代码
#include <stdio.h>
int a[200001];
int b[200001];
int max(int a, int b)
{
return a > b ? a : b;
}
int main()
{
int M, N;
int i, j;
int k;
a[0] = 0;
b[0] = 0;
while (EOF != scanf("%d %d", &M, &N))
{
for (i = 1; i <= M; i++)
{
for (j = 1; j <= N; j++)
{
scanf("%d", &k);
if (1 == j)
a[1] = k;
else
a[j] = max(a[j - 1], a[j - 2] + k);
}
if (1 == i)
b[1] = a[N];
else
b[i] = max(b[i - 1], b[i - 2] + a[N]);
}
printf("%d\n", b[M]);
}
return 0;
}