Apple Tree (POJ2486

來源:互聯網
上載者:User

標籤:get   using   獲得   ffffff   cstring   read   define   poj   傳送門   

                      題目傳送門 題解:

  第一道樹上背包題qaq

  考慮每個節點在最終答案中的類型:1,不經過;2,經過但不返回;3,經過且返回 (返回的定義是最終的停止節點不位於該節點的子樹中)

  對於第一種類型的節點,不用考慮。

  對於後兩種類型,我們設f[i][j][0]表示在第i個節點的子樹中走j步且最終回到i節點所能夠獲得的最大權值,f[i][j][1]表示最終不回到i節點獲得的最大權值。

  對於一個節點的每一個子節點,都要選擇其中的一種狀態。我們可以把該問題抽象成分組背包問題:一個容量為j的背包,有siz組物品(siz相當於子節點數目),每組物品只能選一種。那麼我們可以得到狀態轉移方程: 

  f[i][j][0] = max{f[v][k][0]+f[i][j-k-2][0]} (既然要回到該節點,那麼對於子節點v來說肯定也要回到v節點,且下去上來各一步,故多用掉兩步)

  f[i][j][1] = max{f[v][k][0]+f[i][j-k-2][1]} (對於v節點來說,下去不回來,那麼其他的節點下去後就必須回來)

  f[i][j][1] = max{f[v][k][1]+f[i][j-k-1][0]} (該節點回來,那麼其他節點可以不回來)

 

 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #define LL long long 5 #define RI register int 6 using namespace std; 7 const int INF = 0x7ffffff ; 8 const int N = 100 + 10 ; 9 const int K = 200 + 10 ;10 11 inline int read() {12     int k = 0 , f = 1 ; char c = getchar() ;13     for( ; !isdigit(c) ; c = getchar())14       if(c == ‘-‘) f = -1 ;15     for( ; isdigit(c) ; c = getchar())16       k = k*10 + c-‘0‘ ;17     return k*f ;18 }19 20 struct Edge {21     int to, next ;22 }e[N<<1] ;23 int n, k, cnt = 0 ; int head[N], w[N], f[N][K][2] ;  // 0表示回來,1表示不回來 24 inline void add_edge(int x,int y) {25     e[++cnt].to = y, e[cnt].next = head[x], head[x] = cnt ;26 }27 28 void dfs(int x,int fa) {29     for(int j=0;j<=k;j++) f[x][j][0] = f[x][j][1] = w[x] ;30     for(int i=head[x];i;i=e[i].next) {31         int y = e[i].to ; if(y == fa) continue ;32         dfs(y,x) ;33         for(int j=k;j>=0;j--) {34             for(int kk=0;kk<=j;kk++) {35                 if(j >= kk+2) f[x][j][0] = max(f[x][j][0],f[x][j-kk-2][0]+f[y][kk][0]) ;36                 if(j >= kk+2) f[x][j][1] = max(f[x][j][1],f[x][j-kk-2][1]+f[y][kk][0]) ;37                 if(j >= kk+1) f[x][j][1] = max(f[x][j][1],f[x][j-kk-1][0]+f[y][kk][1]) ;38             }39         }40     }41 }42 43 int main() {44     while(~scanf("%d %d",&n,&k)) {45         cnt = 0 ; memset(head,0,sizeof(head)) ;46         for(int i=1;i<=n;i++) w[i] = read() ;47         for(int i=1;i<n;i++) {48             int x = read(), y = read() ;49             add_edge(x,y) ; add_edge(y,x) ;50         }51         dfs(1,0) ;52         printf("%d\n",max(f[1][k][0],f[1][k][1])) ;53      }54      return 0 ;55 }

   第一次就錯在了子節點中只能有一個下去不回來qwq

Apple Tree (POJ2486

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.