【树形DP】CF 486D,1223E,77C,734E,1249F,490F,935E,960E,101D,629E,1032F,815C

等我有空了再慢慢填题解的坑

  • T1:CF486D Valid Sets
    • title
    • code
  • T2:CF1223E Paint the Tree
    • title
    • code
    • T3:CF77C Beavermuncher-0xFF
    • title
    • code
  • T4:CF734E Anton and Tree
    • title
    • code
  • T5:CF1249F Maximum Weight Subset
    • title
    • code
  • T6:CF490F Treeland Tour
    • title
    • code
  • T7:CF935E Fafa and Ancient Mathematics
    • title
    • code
  • T8:CF960E Alternating Tree
    • title
    • code
  • T9:CF101D Castle
    • title
    • code
  • T10:CF629E Famil Door and Roads
    • title
    • code
  • T11:CF1032F Vasya and Maximum Matching
    • title
    • code
  • T12:CF815C Karen and Supermarket
    • title
    • code

【树形DP】CF 486D,1223E,77C,734E,1249F,490F,935E,960E,101D,629E,1032F,815C_第1张图片

T1:CF486D Valid Sets

title

code

#include 
#include 
using namespace std;
#define lyx 1000000007
#define ll long long
#define MAXN 2005
vector < int > G[MAXN];
int d, n;
ll ans;
ll s[MAXN], dp[MAXN];

void dfs( int u, int fa, int root ) {
	dp[u] = 1;
	for( int i = 0;i < G[u].size();i ++ ) {
		int v = G[u][i];
		if( v == fa ) continue;
		if( ( s[root] > s[v] || ( s[root] == s[v] && root > v ) ) && s[root] - s[v] <= d )
			dfs( v, u, root ), dp[u] = ( dp[u] + dp[u] * dp[v] % lyx ) % lyx;
	}
}

int main() {
	scanf( "%d %d", &d, &n );
	for( int i = 1;i <= n;i ++ )
		scanf( "%lld", &s[i] );
	for( int i = 1, u, v;i < n;i ++ ) {
		scanf( "%d %d", &u, &v );
		G[u].push_back( v );
		G[v].push_back( u );
	}
	for( int i = 1;i <= n;i ++ ) {
		dfs( i, -1, i );
		ans = ( ans + dp[i] ) % lyx;
	}
	printf( "%lld", ans );
	return 0;
}

T2:CF1223E Paint the Tree

title

code

#include 
#include 
#include 
#include 
using namespace std;
#define MAXN 500005
#define ll long long
struct node {
	int v, w;
	node() {}
	node( int V, int W ) {
		v = V, w = W;
	}
};
vector < node > G[MAXN];
int T, n, k;
ll dp[MAXN][2];

bool cmp( int x, int y ) {
	return x > y;
}

void dfs( int u,int fa ) {
	vector < ll > p;
	for( int i = 0;i < G[u].size();i ++ ) {
		int v = G[u][i].v, w = G[u][i].w;
		if( v == fa ) continue;
		dfs( v, u );
		dp[u][1] += dp[v][0];
		dp[u][0] += dp[v][0];
		p.push_back( dp[v][1] + w - dp[v][0] );
	}
	sort( p.begin(), p.end(), cmp );
	for( int i = 0;i < p.size() && i < k;i ++ ) {
		if( p[i] <= 0 ) return;
		if( i < k - 1 ) dp[u][1] += p[i];
		dp[u][0] += p[i];
	}
}

int main() {
	scanf( "%d", &T );
	while( T -- ) {
		scanf( "%d %d", &n, &k );
		for( int i = 1;i <= n;i ++ ) 
			G[i].clear(), dp[i][0] = dp[i][1] = 0;
		for( int i = 1, u, v, w;i < n;i ++ ) {
			scanf( "%d %d %d", &u, &v, &w );
			G[u].push_back( node( v, w ) );
			G[v].push_back( node( u, w ) );
		}
		dfs( 1, 0 );
		printf( "%lld\n", dp[1][0] );
	}
	return 0;
}

T3:CF77C Beavermuncher-0xFF

title

code

#include 
#include 
#include 
using namespace std;
#define ll long long
#define MAXN 100005
#define Pair pair < ll, ll >
vector < int > G[MAXN];
int n, s;
ll k[MAXN], dp[MAXN];

bool cmp( int x, int y ) {
	return x > y;
}

Pair dfs( int u, int fa ) {
	vector < ll > p;
	bool flag = 0;
	ll last = 0;
	for( int i = 0;i < G[u].size();i ++ ) {
		int v = G[u][i];
		if( v == fa ) continue;
		flag = 1;
		Pair son = dfs( v, u );
		last += son.second;
		p.push_back( son.first );	
	}
	if( ! flag ) return make_pair( 0, k[u] - 1 );
	sort( p.begin(), p.end(), cmp );
	ll tot = 0;
	k[u] -= ( u != s );
	for( int i = 0;i < p.size() && k[u];i ++, k[u] -- )
		tot += p[i] + 2;
	tot += ( min( last, k[u] ) << 1 );
	k[u] -= min( last, k[u] );
	return make_pair( tot, k[u] );
}

int main() {
	scanf( "%d", &n );
	for( int i = 1;i <= n;i ++ )
		scanf( "%lld", &k[i] );
	for( int i = 1, u, v;i < n;i ++ ) {
		scanf( "%d %d", &u, &v );
		G[u].push_back( v );
		G[v].push_back( u );
	}
	scanf( "%d", &s );
	Pair ans = dfs( s, -1 );
	printf( "%lld", ans.first );
	return 0;
}

T4:CF734E Anton and Tree

title

code

#include 
#include 
using namespace std;
#define MAXN 200005
struct node {
	int v, w;
	node() {}
	node( int V, int W ) {
		v = V, w = W;
	}
};
vector < node > G[MAXN];
int n, ans;
int c[MAXN], dp[MAXN];

void dfs( int u, int fa ) {
	for( int i = 0;i < G[u].size();i ++ ) {
		int v = G[u][i].v, w = G[u][i].w;
		if( v == fa ) continue;
		dfs( v, u );
		ans = max( ans, dp[u] + dp[v] + w );
		dp[u] = max( dp[u], dp[v] + w );
	}
}

int main() {
	scanf( "%d", &n );
	for( int i = 1;i <= n;i ++ )
		scanf( "%d", &c[i] );
	for( int i = 1, u, v;i < n;i ++ ) {
		scanf( "%d %d", &u, &v );
		int color = ( c[u] != c[v] );
		G[u].push_back( node( v, color ) );
		G[v].push_back( node( u, color ) );
	}
	dfs( 1, 0 );
	printf( "%d", ( ans + 1 ) >> 1 );
	return 0;
}

T5:CF1249F Maximum Weight Subset

title

code

#include 
#include 
#include 
using namespace std;
#define MAXN 205
vector < int > G[MAXN];
int n, k;
int a[MAXN];
int dp[MAXN][MAXN];

void dfs( int u, int fa ) {
	dp[u][0] = a[u];
	for( int i = 0;i < G[u].size();i ++ ) {
		int v = G[u][i];
		if( v == fa ) continue;
		dfs( v, u );
	}
	for( int dep = 0;dep < MAXN;dep ++ ) {
		if( ! dep ) {
			for( int i = 0;i < G[u].size();i ++ ) {
				int v = G[u][i];
				if( v == fa ) continue;
				dp[u][dep] += dp[v][max( k - 1 - dep, 0 )];
			}
		}
		else {
			int temp = 0, ans = 0;
			for( int i = 0;i < G[u].size();i ++ ) {
				int v = G[u][i];
				if( v == fa ) continue;
				temp += dp[v][max( dep - 1, k - dep - 1 )];
			}
			for( int i = 0;i < G[u].size();i ++ ) {
				int v = G[u][i];
				if( v == fa ) continue;
				ans = max( ans, temp - dp[v][max( dep - 1, k - 1 - dep )] + dp[v][dep - 1] );
			}
			dp[u][dep] = max( dp[u][dep], ans );
		}
	}
	for( int i = MAXN - 1;i;i -- )
		dp[u][i - 1] = max( dp[u][i], dp[u][i - 1] );
}

int main() {
	scanf( "%d %d", &n, &k ); k ++;
	for( int i = 1;i <= n;i ++ )
		scanf( "%d", &a[i] );
	for( int i = 1, u, v;i < n;i ++ ) {
		scanf( "%d %d", &u, &v );
		G[u].push_back( v );
		G[v].push_back( u );
	}
	dfs( 1, 0 );
	printf( "%d", dp[1][0] );
	return 0;
}

T6:CF490F Treeland Tour

title

code

#include 
#include 
#include 
#include 
#include 
using namespace std;
#define MAXN 6005
vector < int > G[MAXN];
int n, ans;
int w[MAXN], dp[MAXN];

void dfs( int u, int fa ) {
	int pos = lower_bound( dp + 1, dp + n + 1, w[u] ) - dp;
	ans = max( ans, pos );
	int temp = dp[pos];
	dp[pos] = w[u];
	for( int i = 0;i < G[u].size();i ++ ) {
		int v = G[u][i];
		if( v == fa ) continue;
		dfs( v, u );
	}
	dp[pos] = temp;
}

int main() {
	scanf( "%d", &n );
	for( int i = 1;i <= n;i ++ )
		scanf( "%d", &w[i] );
	for( int i = 1, u, v;i < n;i ++ ) {
		scanf( "%d %d", &u, &v );
		G[u].push_back( v );
		G[v].push_back( u );
	}
	memset( dp, 0x7f, sizeof( dp ) );
	for( int i = 1;i <= n;i ++ ) dfs( i, 0 );
	printf( "%d", ans );
	return 0;
}

T7:CF935E Fafa and Ancient Mathematics

title

code

#include 
#include 
#include 
using namespace std;
#define MAXN 10005
#define lson son[u][0]
#define rson son[u][1]
int add, sub, minn;
char s[10005];
int fa[10005];
int son[10005][2];
int dp[10005][105][2];

void dfs( int u ) {
	if( ! lson ) return;
	dfs( lson ), dfs( rson );
	for( int i = 0;i <= minn;i ++ )
		for( int j = 0;i + j <= minn;j ++ ) {
			dp[u][i + j + ( add < sub )][0] = max( dp[u][i + j + ( add < sub )][0], dp[lson][i][0] + dp[rson][j][0] );
			dp[u][i + j + ( add >= sub )][0] = max( dp[u][i + j + ( add >= sub )][0], dp[lson][i][0] - dp[rson][j][1] );
			dp[u][i + j + ( add < sub )][1] = min( dp[u][i + j + ( add < sub )][1], dp[lson][i][1] + dp[rson][j][1] );
			dp[u][i + j + ( add >= sub )][1] = min( dp[u][i + j + ( add >= sub )][1], dp[lson][i][1] - dp[rson][j][0] );
		}
}

int main() {
	scanf( "%s %d %d", s + 1, &add, &sub );
	minn = min( add, sub );
	int len = strlen( s + 1 ), rt = 1, tot = 1;
	for( int i = 1;i <= len;i ++ )
		for( int j = 0;j <= minn;j ++ )
			dp[i][j][0] = -1e9, dp[i][j][1] = 1e9;
	for( int i = 1;i <= len;i ++ ) {
		if( s[i] == '(' || s[i] == '?' ) son[rt][son[rt][0] ? 1 : 0] = ++ tot, fa[tot] = rt, rt = tot;
		else if( s[i] == ')' ) rt = fa[rt];
		else dp[tot][0][0] = dp[tot][0][1] = s[i] - '0', rt = fa[rt];
	}
	dfs( 1 );
	printf( "%d", dp[1][minn][0] );
	return 0;
}

T8:CF960E Alternating Tree

title

code

#include 
#include 
#include 
using namespace std;
#define MAXN 200005
#define mod 1000000007
#define ll long long
vector < int > G[MAXN];
int n;
ll ans;
ll a[MAXN], fa[MAXN], siz[MAXN], f[MAXN], g[MAXN], uf[MAXN], ug[MAXN];

void dfs( int u ) {
	f[u] = siz[u] = 1;
	for( int i = 0;i < G[u].size();i ++ ) {
		int v = G[u][i];
		if( v == fa[u] ) continue;
		fa[v] = u, dfs( v );
		siz[u] += siz[v], f[u] += g[v], g[u] += f[v];
	}
	ans = ( ans + ( f[u] - g[u] ) * ( n - siz[u] + 1 ) % mod * a[u] % mod ) % mod;
	ans = ( ans + ( siz[u] - 1 ) * a[u] % mod ) % mod;
	for( int i = 0;i < G[u].size();i ++ ) {
		int v = G[u][i];
		if( v == fa[u] ) continue;
		ans = ( ans + ( g[v] - f[v] ) * ( siz[u] - siz[v] - 1 ) % mod * a[u] % mod ) % mod;
	}
}

void bfs() {
	queue < int > q;
	for( int i = 0;i < G[1].size();i ++ )
		q.push( G[1][i] );
	while( ! q.empty() ) {
		int u = q.front(); q.pop();
		uf[u] = ug[fa[u]] + g[fa[u]] - f[u];
		ug[u] = uf[fa[u]] + f[fa[u]] - g[u];
		ans = ( ans + ( uf[u] - ug[u] ) * siz[u] % mod * a[u] % mod ) % mod;
		for( int i = 0;i < G[u].size();i ++ ) {
			int v = G[u][i];
			if( v == fa[u] ) continue;
			q.push( v );
		}
	}
}

int main() {
	scanf( "%d", &n );
	for( int i = 1;i <= n;i ++ )
		scanf( "%lld", &a[i] );
	for( int i = 1, u, v;i < n;i ++ ) {
		scanf( "%d %d", &u, &v );
		G[u].push_back( v );
		G[v].push_back( u );
	}
	dfs( 1 );
	bfs();
	printf( "%lld" , ( ans + mod ) % mod );
	return 0;
}

T9:CF101D Castle

title

code

#include 
#include 
#include 
using namespace std;
#define MAXN 100005
#define ll long long
struct edge {
	int v, w;
	edge(){}
	edge( int V, int W ) {
		v = V, w = W;
	}
};
struct node {
	ll x, y, z;
	node(){}
	node( ll X, ll Y, ll Z ) {
		x = X, y = Y, z = Z;
	}
}p[MAXN];
vector < edge > G[MAXN];
int n;
ll f1[MAXN], f2[MAXN], Size[MAXN];

bool cmp( node u, node v ) {
	return v.x * u.y < u.x * v.y;
}

void dfs( int u, int fa ) {
	Size[u] ++;
	for( int i = 0;i < G[u].size();i ++ ) {
		int v = G[u][i].v;
		if( v == fa ) continue;
		dfs( v, u );
		Size[u] += Size[v], f1[u] += f1[v];
	}
	int len = 0;
	for( int i = 0;i < G[u].size();i ++ ) {
		int v = G[u][i].v, w = G[u][i].w;
		if( v == fa ) continue;
		p[++ len] = node( Size[v], f2[v] + ( w << 1 ), w );
	}
	sort( p + 1, p + len + 1, cmp );
	for( int i = 1;i <= len;i ++ )
		f1[u] += ( p[i].z + f2[u] ) * p[i].x, f2[u] += p[i].y;
}

int main() {
	scanf( "%d", &n );
	for( int i = 1, u, v, w;i < n;i ++ ) {
		scanf( "%d %d %d", &u, &v, &w );
		G[u].push_back( edge( v, w ) );
		G[v].push_back( edge( u, w ) );
	}
	dfs( 1, 0 );
	printf( "%.8f", f1[1] * 1.0 / ( n - 1 ) );
	return 0;
}

T10:CF629E Famil Door and Roads

title

code

#include 
#include 
#include 
using namespace std;
#define ll long long
#define MAXN 100005
vector < int > G[MAXN]; 
int n, m;
ll dep[MAXN], siz[MAXN], f[MAXN][20], sum[MAXN], tot[MAXN];

void dfs1( int u, int fa ) {
	siz[u] = 1, dep[u] = sum[u] = dep[fa] + 1, f[u][0] = fa;
	for( int i = 0;i < G[u].size();i ++ ) {
		int v = G[u][i];
		if( v == fa ) continue;
		dfs1( v, u ), sum[u] += sum[v], siz[u] += siz[v];
	}
}

void dfs2( int u ) {
	int fa = f[u][0];
	if( fa ) {
		tot[u] = tot[fa] + sum[fa] - sum[u];
		tot[u] -= ( ( siz[fa] - siz[u] ) * dep[fa] ) << 1;
	}
	for( int i = 0;i < G[u].size();i ++ )
		if( G[u][i] != fa ) dfs2( G[u][i] );
}

int jump( int x, int s ) {
	for( int i = 0;i < 18;i ++ )
		if( ( 1 << i ) & s ) x = f[x][i];
	return x;
}

int LCA( int x, int y ) {
	if( dep[x] < dep[y] ) swap( x, y );
	x = jump( x, dep[x] - dep[y] );
	if( x == y ) return x;
	for( int i = 17;~ i;i -- )
		if( f[x][i] != f[y][i] ) x = f[x][i], y = f[y][i];
	return f[x][0];
}

int main() {
	scanf( "%d %d", &n, &m );
	for( int i = 1, u, v;i < n;i ++ ) {
		scanf( "%d %d", &u, &v );
		G[u].push_back( v );
		G[v].push_back( u );
	}
	dfs1( 1, 0 ), dfs2( 1 );
	for( int j = 1;j < 18;j ++ )
		for( int i = 1;i <= n;i ++ )
			f[i][j] = f[f[i][j - 1]][j - 1];
	for( int i = 1, u, v;i <= m;i ++ ) {
		scanf( "%d %d", &u, &v );
		if( dep[u] > dep[v] ) swap( u, v );
		int lca = LCA( u, v );
		ll ans = 0, all = 0;
		if( lca == u ) {
			int son = jump( v, dep[v] - dep[u] - 1 );
			all = siz[v] * ( siz[1] - siz[son] );
			ans += ( sum[v] - dep[v] * siz[v] ) * ( siz[1] - siz[son] );
			ans += ( dep[v] - dep[u] ) * all;
			ans += all;
			ans += siz[v] * dep[u] * ( siz[1] - siz[son] ) + tot[son] * siz[v];
		}
		else {
			all = siz[u] * siz[v];
			ans += siz[u] * ( sum[v] - dep[v] * siz[v] );
			ans += siz[v] * ( sum[u] - siz[u] * dep[u] );
			ans += all * ( dep[u] + dep[v] - ( dep[lca] << 1 ) + 1 );
		}
		printf( "%.8f\n", ans * 1.0 / all );
	}
	return 0;
}

T11:CF1032F Vasya and Maximum Matching

title

code

#include 
#include 
#include 
using namespace std;
#define MAXN 300005
#define mod 998244353
#define ll long long
vector < int > G[MAXN];
int n;
ll dp[MAXN][3], g[3];
//0-合法
//1-非法
//2-孤 
void dfs( int u, int fa ) {
	dp[u][2] = 1;
	for( int i = 0;i < G[u].size();i ++ ) {
		int v = G[u][i];
		if( v == fa ) continue;
		dfs( v, u );
		g[0] = ( ( dp[v][2] + dp[v][1] ) % mod * dp[u][2] % mod 
		   	   + ( dp[v][2] + dp[v][1] ) % mod * dp[u][1] % mod
			   + ( dp[v][2] + ( dp[v][0] << 1 ) ) % mod * dp[u][0] % mod ) % mod;
		g[1] = ( dp[v][0] * dp[u][2] % mod + ( dp[v][2] + ( dp[v][0] << 1 ) ) % mod * dp[u][1] % mod ) % mod;
		g[2] = ( dp[v][0] + dp[v][2] ) % mod * dp[u][2] % mod;
		swap( dp[u], g );	
	}
}

int main() {
	scanf( "%d", &n );
	for( int i = 1, u, v;i < n;i ++ ) {
		scanf( "%d %d", &u, &v );
		G[u].push_back( v );
		G[v].push_back( u );
	}
	dfs( 1, 0 );
	printf( "%lld\n", ( dp[1][0] + dp[1][2] ) % mod );
	return 0;
}

T12:CF815C Karen and Supermarket

title

code

#include 
#include 
#include 
#include 
using namespace std;
#define MAXN 5005
vector < int > G[MAXN];
int n, b;
int c[MAXN], d[MAXN], siz[MAXN];
int dp[MAXN][MAXN][2];

void dfs( int u ) {
	siz[u] = 1;
	dp[u][0][0] = 0, dp[u][1][0] = c[u], dp[u][1][1] = c[u] - d[u];
	for( int i = 0;i < G[u].size();i ++ ) {
		int v = G[u][i];
		dfs( v );
		for( int j = siz[u];j >= 0;j -- )
			for( int k = 0;k <= siz[v];k ++ ) {
				dp[u][j + k][0] = min( dp[u][j][0] + dp[v][k][0], dp[u][j + k][0] );
				dp[u][j + k][1] = min( dp[u][j + k][1], dp[u][j][1] + min( dp[v][k][0], dp[v][k][1] ) );
			}
		siz[u] += siz[v];
	}
}

int main() {
	scanf( "%d %d", &n, &b );
	for( int i = 1, fa;i <= n;i ++ ) {
		scanf( "%d %d", &c[i], &d[i] );
		if( i > 1 )
			scanf( "%d", &fa ), G[fa].push_back( i );
	}
	memset( dp, 0x3f, sizeof( dp ) );
	dfs( 1 );
	for( int i = n;~ i;i -- )	
		if( dp[1][i][0] <= b || dp[1][i][1] <= b )
			return ! printf( "%d", i );
	return 0;
}

你可能感兴趣的:(#,树形DP)