当前位置 : 主页 > 网络编程 > 其它编程 >

NC19810kingdom(dp)

来源:互联网 收集:自由互联 发布时间:2023-07-02
想不到的一道题,有点背包的感觉,但是重点还是题目所给的信息首先观察题目应该是平方算法进一步剖析,我只能想到枚举重儿子大小这个思路。后来看了题解发现他们把信息挖掘的
想不到的一道题,有点背包的感觉,但是重点还是题目所给的信息首先观察题目应该是平方算法进一步剖析,我只能想到枚举重儿子大小这个思路。后来看了题解发现他们把信息挖掘的很到位。重儿子肯定

想不到的一道题,有点背包的感觉,但是重点还是题目所给的信息

首先观察题目应该是平方算法

进一步剖析,我只能想到枚举重儿子大小这个思路。

后来看了题解发现他们把信息挖掘的很到位。重儿子肯定是要枚举

现在求的是最大代价,而除了重儿子外,自顶向下的思路上看,还有很多其他子树,这些树组成了森林

如果求他的最大代价比较关键,题目其实没啥信息,有的比如节点个数,最大是平方算法,其他儿子不能大于所选的重儿子,所以把这些信息结合起来产生了一种状态设计f[i][j]

表示以i个节点,最大的子树个数不超过j的森林的最大代价。

这样就可以枚举更新了,而这个dp,因为是最大,所以首先要从f[i][j-1]更新过来,因为子状态包括他,其次就要考虑节点个数的变化

那么这个森林的更新就可以枚举,用ans[j]+f[i-j][j]这样的状态去更新,因为森林肯定是很多树,我们枚举其中一棵树的大小,那么其他树仍然组成了一个森林,并且因为这是小状态所以已经被计算了。

这样从宏观上理解就比较清晰了。

技术分享图片技术分享图片

#includeusing namespace std;typedef long long ll;typedef pair pll;const int N=3e5+10;int f[8080][8080];int ans[N];int main(){ ios::sync_with_stdio(false); int n; cin>>n; int i,j; for(i=1;i<=n;i++){ for(j=1;j=i) f[j][i]=f[j][i-1]; if(j>=i) f[j][i]=max(f[j][i],f[j-i][i]+ans[i]); } } cout

上一篇:mysql主从复制机制排错过程
下一篇:没有了
网友评论