nssl1196-摘果子【树形依赖背包,dp】
生活随笔
收集整理的這篇文章主要介紹了
nssl1196-摘果子【树形依赖背包,dp】
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
正題
題目大意
有n個(gè)東西,每個(gè)東西有價(jià)值和價(jià)格,然后要求一個(gè)價(jià)格上限,和除了第一個(gè)東西以外都有一個(gè)買這個(gè)之前必須要買的東西。
求最大價(jià)值
解題思路
我們考慮之前的樹形背包
然后發(fā)現(xiàn)時(shí)間復(fù)雜度O(n3)O(n^3)O(n3),之后我們考慮一個(gè)方法
之前是將子節(jié)點(diǎn)合并起來所以時(shí)間會很久,可是我們可以將一個(gè)子節(jié)點(diǎn)處理好,然后直接仍給它的下一個(gè)兄弟,這樣就可以O(n2)O(n^2)O(n2)解決這個(gè)問題
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)//計(jì)算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])); }總結(jié)
以上是生活随笔為你收集整理的nssl1196-摘果子【树形依赖背包,dp】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 泪目了!三星暗示S20和Note 20老
- 下一篇: nssl1195-健美猫【???】