牛客练习赛89-牛牛种小树-(思维+转化背包)

D

题意:
就是让你构造一个n个点的数,然后,一个点度为i的权值为va[i]现在问你构造出的树,最大的权值和是多少。

思考:
刚开始看到感觉就是一共2*(n-1)个度,然后直接完全背包跑一遍,但是不对。然后就去吃饭了,其实,那样做不对的原因是,有的点你可能赋的是0度,每个点至少是一个度,这一点我没想到。所以每个点先分配一个度,然后剩下n-2个度,再去跑完全背包就可以了。值得注意的是,要初始化,因为dp的定义就是确定的时候,所以要确定好。还有就是,有可能想到这个做法但是敢写,万一组不成一个树呢?但是你仔细想一下,如果真要去构造树,这得多难,所以往简单的思路去想,应该是对的。

代码:

二维的:

int T,n,m,k;
int va[N];
int dp[M][M]; //走到i点用了j度的最大权值和。

signed main()
{
	IOS;
	cin>>n;
	m = 2*n-2;
	for(int i=1;i<=n-1;i++) cin>>va[i];
	for(int i=0;i<=n;i++) for(int j=0;j<=m;j++) dp[i][j] = -inf; //注意要初始化,因为函数的定义就是确定是多少,所以要先初始化好
	dp[0][0] = 0;
	for(int i=1;i<=n;i++)
	{
		for(int k=0;k<=m;k++)
		{
			for(int j=1;j<=n-1;j++)
			if(k>=j) dp[i][k] = max(dp[i][k],dp[i-1][k-j]+va[j]);
		}
	}
	cout<<dp[n][m];
	return 0;
}

一维:
int T,n,m,k;
int va[N];
int dp[N];

signed main()
{
	IOS;
	cin>>n;
	m = n-2;
	for(int i=1;i<=n-1;i++) cin>>va[i];
	for(int i=0;i<=m;i++) dp[i] = -inf;
	dp[0] = n*va[1];
	for(int i=1;i<=n-2;i++) //给某个点分配这些点,也就是方案数
	{
		for(int j=i;j<=m;j++)
		dp[j] = max(dp[j],dp[j-i]+va[i+1]-va[1]); //减去1是选择一个节点让他度变成i+1,为什么是完全背包呢,因为一共n个点,不管你怎么分配这n-2个度,都不会用完这n个度为1的点。
	}
	cout<<dp[m];
	return 0;
}

总结:
多多思考多多总结。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值