您的位置:首页 > 其它

BZOJ 4813: [Cqoi2017]小Q的棋盘 (树形dp)

2017-04-27 16:21 369 查看
题目传送门

Solution

树形背包dp大水题,是POJ某道题的弱化版。。。不想说了,据说贪心也能过此题。。

一开始50分,dp数组初始化炸了,表示无语。。

Code

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#define N 111

using namespace std;

int n, v, cur, head_p
;
int dp

[2];
struct Tadj{int next, obj;} Edg[N<<1];

void Insert(int a, int b){
cur ++;
Edg[cur].next = head_p[a];
Edg[cur].obj = b;
head_p[a] = cur;
}

void dfs(int root, int fa){
for(int i = head_p[root]; ~ i; i = Edg[i].next){
int v = Edg[i].obj;
if(v == fa)  continue;
dfs(v, root);
for(int j = n; j >= 1; j--)
for(int k = 1; k <= j; k++){
if(k >= 2){
dp[root][j][0] = max(dp[root][j][0], dp[v][k-2][0] + dp[root][j-k][0]);
dp[root][j][1] = max(dp[root][j][1], dp[v][k-2][0] + dp[root][j-k][1]);
}
dp[root][j][1] = max(dp[root][j][1], dp[v][k-1][1] + dp[root][j-k][0]);
//这里其实还有一个状态不过是废的
//就是让它回到儿子节点但不回到子树的根(明显这不优)
}
}
}

int main(){

scanf("%d%d", &v, &n);
for(int i = 1; i <= v; i++)  head_p[i] = -1;
cur = -1;
int a, b;
for(int i = 1; i < v; i++){
scanf("%d%d", &a, &b);
Insert(a+1, b+1);
Insert(b+1, a+1);
}
memset(dp, 0, sizeof(dp));
for(int i = 1; i <= v; i++)
for(int j = 0; j <= n; j++)  dp[i][j][0] = dp[i][j][1] = 1;//初始化

dfs(1, 0);
printf("%d\n", max(dp[1]
[0], dp[1]
[1]));

return 0;
}


用力踩,那不堪一击的洁白。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: