nssl1196-摘果子【树形依赖背包,dp】
生活随笔
收集整理的這篇文章主要介紹了
nssl1196-摘果子【树形依赖背包,dp】
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
正題
題目大意
有n個東西,每個東西有價值和價格,然后要求一個價格上限,和除了第一個東西以外都有一個買這個之前必須要買的東西。
求最大價值
解題思路
我們考慮之前的樹形背包
然后發現時間復雜度O(n3)O(n^3)O(n3),之后我們考慮一個方法
之前是將子節點合并起來所以時間會很久,可是我們可以將一個子節點處理好,然后直接仍給它的下一個兄弟,這樣就可以O(n2)O(n^2)O(n2)解決這個問題
code
#include<cstdio> #include<algorithm> #define N 2010 using namespace std; struct node{int to,next; }a[N*2]; int n,m,dfn[N],size[N],ls[N],f[N][N],tot,cnt,v[N],p[N],x,y; void addl(int x,int y) {a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot; } void dfs(int x,int fa)//計算dfs序和子樹大小 {dfn[++cnt]=x;size[x]=1;for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(y==fa) continue;dfs(y,x);size[x]+=size[y];} } int main() {scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)scanf("%d%d",&v[i],&p[i]);for(int i=1;i<n;i++){scanf("%d%d",&x,&y);addl(x,y);addl(y,x);}dfs(1,0);for(int i=n;i>=1;i--){int x=dfn[i];for(int j=0;j<=m;j++) f[i][j]=max(f[i+size[x]][j],0);//繼承兄弟for(int j=p[x];j<=m;j++)f[i][j]=max(f[i][j],f[i+1][j-p[x]]+v[x]);//處理}printf("%d",max(0,f[1][m])); }總結
以上是生活随笔為你收集整理的nssl1196-摘果子【树形依赖背包,dp】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 泪目了!三星暗示S20和Note 20老
- 下一篇: 斯巴鲁将从2025年开始采用特斯拉北美充