2021辽宁省赛——H制造游戏币

题目链接

题意:
n n n 个点构成若干条链,每个点有一个权值且可以选任意次,父节点的选择次数必须严格大于子结点,求最后权值总和为 T T T 的方案数

题解:

由于是严格大于,所以对于一条链,从叶子节点往上,先依次选择 0 , 1 , 2 , 3... 0,1,2,3... 0,1,2,3... 次,然后把子结点的权值变成本身加父节点权值之和,这样选择子结点就相当于子结点和父节点一起选,保证父节点选择次数一直大于子结点

void problem_solver() {
	int n,m,T; cin>>n>>m>>T;
	vector<int>a(n+1),son(n+1),head(n+1,1),dep(n+1);
	for(int i=1;i<=n;i++) cin>>a[i];
	vector b=a;
	for(int i=0;i<m;i++){
		int u,v; cin>>u>>v;
		son[u]=v,head[v]=0;
	} 
	function<void(int)>dfs=[&](int u){
		if(son[u]){
			a[son[u]]+=a[u];
			dfs(son[u]);
			dep[u]=dep[son[u]]+1;
		}
	};
	for(int i=1;i<=n;i++) if(head[i]) dfs(i);
	for(int i=1;i<=n;i++) T-=dep[i]*b[i];
	if(T<0){
		cout<<0<<'\n';
		return;
	}
	vector<int>dp(T+1);
	dp[0]=1;
	for(int i=1;i<=n;i++)
		for(int j=a[i];j<=T;j++) 
			dp[j]=(dp[j-a[i]]+dp[j])%mod;
	cout<<dp[T]<<'\n';
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值