您的位置:首页 > 其它

LightOJ - 1217 Neighbor House (II)(dp)

2015-10-31 23:47 239 查看
题目大意:有N个点围成一个环,每个点都有相应的价值。现在要求你挑选点,使得点的价值和最大,但是有一个限制条件,挑选的点不能相邻

解题思路:如果不是环的话,就好解决了,用dp[i][0]表示挑选到了第i个,第i个不要的最大价值

dp[i][1]表示挑选到了第i个,要第i个的最大价值

现在是环了,那只要讨论一下最大价值里面是否包含了第一个或者最后一个,如果其中一个不包含,则最大价值不变,因为不会违反规则

如果包含了,就选择去掉一个即可

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1010;

int val
;
int n, cas  = 1;
int dp
[2], NoFirst
[2];
void init() {
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d", &val[i]);
}

void solve() {
memset(dp, 0, sizeof(dp));
memset(NoFirst, 0, sizeof(NoFirst));

dp[1][0] = NoFirst[2][0] = 0;
dp[1][1] = val[1];
NoFirst[2][1] = val[2];
for (int i = 2; i <= n; i++) {
dp[i][0] = max(dp[i - 1][0], dp[i - 1][1]);
dp[i][1] = dp[i - 1][0] + val[i];
}

for (int i = 3; i <= n; i++) {
NoFirst[i][0] = max(NoFirst[i - 1][0], NoFirst[i - 1][1]);
NoFirst[i][1] = NoFirst[i - 1][0] + val[i];
}

//1.如果不买最后一个所能的收益大于等于买了最后一个的收益,表示最后一个可买可不买,那就选择不买,这样就不会和第一个冲突了
//2.如果不考虑第一个所能得到的收益大于等于考虑了第一个的收益,则表明第一个可买可不买
//3.如果以上两种情况都不成立,表明第一个或者最后一个得舍去了
if (dp
[0] >= dp
[1]) printf("Case %d: %d\n", cas++, dp
[0]);
else if (max(NoFirst
[0], NoFirst
[1]) >= dp
[1])
printf("Case %d: %d\n", cas++, max(NoFirst
[0], NoFirst
[1]));
else printf("Case %d: %d\n", cas++, max(max(dp[n - 1][0], dp[n - 1][1]), max(NoFirst
[0], NoFirst
[1])));
}

int main() {
int test;
scanf("%d", &test);
while (test--) {
init();
solve();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: