BZOJ 1813 [Cqoi2017]小Q的棋盘 ——树形DP
2024-08-24 20:43:05
唔,貌似以前做过这样差不多的题目。
用$f(i,0/1)$表示从某一点出发,只能走子树的情况下回到根、不回到根的最多经过不同的点数。
然后就可以DP辣
#include <map>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define F(i,j,k) for (int i=j;i<=k;++i)
#define D(i,j,k) for (int i=j;i>=k;--i)
#define ll long long
#define mp make_pair int dp[105][105][2],n,m;
int h[205],to[205],ne[205],en=0; void add(int a,int b)
{to[en]=b;ne[en]=h[a];h[a]=en++;} void Finout()
{
freopen("chessboard.in","r",stdin);
freopen("chessboard.out","w",stdout);
} void dfs(int o,int fa)
{
dp[o][0][1]=1;
for (int i=h[o];i>=0;i=ne[i])
if (to[i]!=fa)
{
dfs(to[i],o);
for (int j=m;j>=0;--j)
{
for (int k=0;k<=j-2;++k)
dp[o][j][1]=max(dp[o][j][1],dp[to[i]][k][1]+dp[o][j-k-2][1]);
for (int k=0;k<=j-2;++k)
dp[o][j][0]=max(dp[o][j][0],dp[to[i]][k][1]+dp[o][j-k-2][0]);
for (int k=0;k<=j-1;++k)
dp[o][j][0]=max(dp[o][j][0],dp[to[i]][k][0]+dp[o][j-k-1][1]);
}
}
for (int j=m;j>=0;--j)
dp[o][j][0]=max(dp[o][j][0],dp[o][j][1]);
} int main()
{
memset(dp,-0x3f,sizeof dp);
memset(h,-1,sizeof h);
scanf("%d%d",&n,&m);
F(i,1,n-1)
{
int a,b;
scanf("%d%d",&a,&b);
a++;b++;add(a,b);add(b,a);
}
dfs(1,-1);
int ans=-1;
F(i,0,m) ans=max(ans,max(dp[1][i][0],dp[1][i][1]));
printf("%d\n",ans);
}
最新文章
- EF6 的性能优化
- cad中关于点样式点的绘制
- 找规律 ZOJ3498 Javabeans
- 新浪微博客户端(32)-设置相册图片的contentMode
- Unable to instantiate Action...............
- OpenGL的glViewport视口变换函数详解[转]
- PLSQL_PLSQL读和写XML文件方式(案例)
- 545B. Equidistant String
- Umbraco(5)-Creating Master Template Part 1(翻译文档)
- 【linux】
- 利用Java自带的MD5加密java.security.MessageDigest;
- HDU 1021 - Fibonacci Again
- Openlayer 3 的点击弹出框
- 支持Angular 2的表格控件
- JavaWeb开发技术基础概念回顾篇
- Jquery笔记之第一天
- Android开发技巧——自定义单选或多选的ListView
- 记一次JVM故障排除
- day16匿名函数
- CSS制作渐变背景色