三道簡單樹型dp+01背包~~hdu1561,poj1947,zoj3626

以前學樹型dp就是隨便的看了幾道題,沒有特別注意樹型dp中的小分類的總結,直到上次浙大月賽一道很簡單的樹型dp都不會,才意識到自己太水了~~come on!

hdu1561:題目給出了很多棵有根樹,如果把每棵樹的根節點都與0相連,則就是一棵完整的有根樹了(N<=200),ACboy從根節點出發,他最多可以攻占m個城市,而每個城市的財富值不一定相同,問ACboy最多可以獲得多少財富。就是以每個跟節點做01背包就可以了,dp[i][j]表示以i為根節點已經攻占了j個城市獲得的最大財富。不過要注意一下最后要加上根節點的值,因為要求攻占了根節點才能往下攻占,當然節點0除外,具體見代碼和注釋:

View Code
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<algorithm>
 6 #include<vector>
 7 #define see(x) cout<<#x<<":"<<x<<endl;
 8 using namespace std;
 9 const int maxn = 205;
10 int w[maxn], dp[maxn][maxn];
11 vector<int> son[maxn];
12 int n, m;
13 void dfs(int x){
14     int i, j, k;
15     if(son[x].size()==0){
16         dp[x][1] = w[x];
17         return;
18     }
19     for(i=0;i<son[x].size();i++){
20         dfs(son[x][i]);
21     }
22     for(i=0;i<son[x].size();i++){
23         for(j=m;j>=0;j--){
24             for(k=0;k<=j;k++){
25                 if(dp[son[x][i]][k]!=-1&&dp[x][j-k]!=-1){
26                     dp[x][j] = max(dp[x][j],dp[son[x][i]][k]+dp[x][j-k]);
27                 }
28             }
29         }
30     }
31 /*上面就是基本樹型DP加背包的基本解法了*/
32     if(x!=0){  //x為0節點時,不需要這種要求
33         for(j=m;j>=0;j--){//處理一下必須攻占根節點才能攻占剩下的子節點的條件,逆序正好可以處理完
34             if(dp[x][j-1]!=-1){
35                 dp[x][j] = dp[x][j-1]+w[x];
36             }
37         }
38     }
39 }
40 void Init(int n){
41     memset(dp,-1,sizeof(dp));
42     for(int i=0;i<=n;i++){
43         dp[i][0] = 0;
44     }
45     for(int i=0;i<=n;i++){
46         son[i].clear();
47     }
48 }
49 int main(){
50     int i, j, k, l;
51     while(~scanf("%d%d",&n,&m)&&(n||m)){
52         Init(n);
53         for(i=1;i<=n;i++){
54             scanf("%d%d",&k,&w[i]);
55             son[k].push_back(i);
56         }
57         w[0] = 0; dfs(0);
58         printf("%d\n",dp[0][m]);
59     }
60 }

poj1947:給出一棵有根樹,問孤立出大小為P的子樹要斷開多少邊。就是一個容量為p的背包,樹型dp。dp[i][j]表示以i為根孤立出j個節點的樹至少需要斷開多少條邊,于是dp[x][j] = min{dp[x1][j1]+dp[x2][j2]+dp[x3][j3]+……+dp[xn][jn]},j1+j2+j3+……+jn = j,但是也不是完全這樣了,其實在對每個背包進行更新時,應該是dp[x][j] = min{dp[x][j],dp[son[x][i]][k]+dp[x][j-k]-2},減2是因為要減去算了兩次的x到son[x][i]的那條邊,具體見代碼,寫的挺糾結的。

View Code
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<cstring>
 6 #include<vector>
 7 using namespace std;
 8 const int maxn = 155;
 9 vector<int> son[maxn];
10 bool vis[maxn];
11 int dp[maxn][maxn];
12 int n, p;
13 void dfs(int root, int x){
14     int i, j, k;
15     if(x==root) dp[x][1] = son[x].size();
16     else dp[x][1] = son[x].size()+1;
17 
18     for(i=0;i<son[x].size();i++){
19         dfs(root,son[x][i]);
20     }
21     for(i=0;i<son[x].size();i++){
22         for(j=p;j>=0;j--){
23             for(k=0;k<=j;k++){
24                 if(dp[x][k]<maxn&&dp[son[x][i]][j-k]<maxn){
25                     dp[x][j] = min(dp[x][j],dp[x][k]+dp[son[x][i]][j-k]-2);
26                 }
27             }
28         }
29     }
30 }
31 void Init(int n){
32     int i, j;
33     for(i=0;i<=n;i++){
34         for(j=0;j<=n;j++){
35             dp[i][j] = maxn;
36         }
37         son[i].clear();
38         vis[i] = 0;
39     }
40 }
41 int main(){
42     int i, j, k, x1, x2, ans;
43     while(~scanf("%d%d",&n,&p)){
44         Init(n);
45         for(i=0;i<n-1;i++){
46             scanf("%d%d",&x1,&x2);
47             son[x1].push_back(x2);
48             vis[x2] = 1;
49         }
50         for(i=1;i<=n;i++){
51             if(!vis[i]){
52                 dfs(i,i);break;
53             }
54         }
55         ans = maxn;
56         for(i=1;i<=n;i++){
57             ans = min(ans,dp[i][p]);
58         }
59         printf("%d\n",ans);
60     }
61 }

zoj3626:這個就是上次浙大月賽的題了,題意跟hdu1561類似,給出一棵樹,n-1條邊有不同的邊全,n個城市有不同的財富,一個人最多只可以走m/2長度,為最多可以占領多少財富。dp[i][j]表示以i為根繼續走了j個長度可以獲得的最大財富,自己就是在刷完hdu1561之后簡單的改改順利的a了,兩道題可能可以改成一樣的寫法,不過想到怎么寫,就怎么寫了

View Code
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<algorithm>
 6 #include<vector>
 7 #define see(x) cout<<#x<<":"<<x<<endl;
 8 using namespace std;
 9 const int maxn = 110;
10 vector<int> son[maxn], w[maxn];
11 int val[maxn];
12 int dp[maxn][205];
13 int n, m;
14 void dfs(int x, int pre){
15     int i, j, k;
16     if(son[x].size()==1&&pre==son[x][0]){
17         return;
18     }
19     for(i=0;i<son[x].size();i++){
20         if(pre!=son[x][i]){
21             dfs(son[x][i],x);
22         }
23     }
24     for(i=0;i<son[x].size();i++){
25         if(pre!=son[x][i]){
26             for(j=m-w[x][i];j>=0;j--){
27                 for(k=0;k<=j;k++){
28                     if(dp[son[x][i]][k]!=-1&&dp[x][j-k]!=-1){
29                         dp[x][j+w[x][i]] = max(dp[x][j+w[x][i]],dp[son[x][i]][k]+dp[x][j-k]);
30                     }
31                 }
32             }
33         }
34     }
35 }
36 void Init(int n){
37     memset(dp,-1,sizeof(dp));
38     for(int i=0;i<=n;i++){
39         son[i].clear();
40         w[i].clear();
41     }
42 }
43 int main(){
44     int i, j, k, x1, x2, l, ans;
45     while(~scanf("%d",&n)){
46         Init(n);
47         for(i=1;i<=n;i++){
48             scanf("%d",&val[i]);
49             dp[i][0] = val[i];
50         }
51         for(i=0;i<n-1;i++){
52             scanf("%d%d%d",&x1,&x2,&l);
53             son[x1].push_back(x2);w[x1].push_back(l);
54             son[x2].push_back(x1);w[x2].push_back(l);
55         }
56         scanf("%d%d",&k,&m);
57         m/=2;dfs(k,-1);
58         ans = val[k];
59         for(i=0;i<=m;i++){
60             ans = max(ans,dp[k][i]);
61         }
62         printf("%d\n",ans);
63     }
64 }

?按理說dp都沒啥模板,但是其實樹上dp+背包,如果不復雜的化,也有點按部就班的感覺了~下次想出狀態,尋軌道距應該就能做出來了。

轉載于:https://www.cnblogs.com/celia01/archive/2012/08/02/2619063.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/377288.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/377288.shtml
英文地址,請注明出處:http://en.pswp.cn/news/377288.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

css 字體圖標更改顏色_在CSS中更改字體

css 字體圖標更改顏色CSS字體屬性 (CSS font properties ) Font properties in CSS is used to define the font family, boldness, size, and the style of a text. CSS中的字體屬性用于定義字體系列 &#xff0c; 粗體 &#xff0c; 大小和文本樣式 。 Syntax: 句法&#xf…

深入new/delete:Operator new的全局重載

Operator new 的全局重載 原文地址&#xff1a;http://blog.csdn.net/zhenjing/article/details/4354880 我們經常看到這么一句話&#xff1a; operator new 可以重載&#xff0c; placement new 不可重載。其實此處所說的不可重載應該是指全局的 placement new 不可重載&#…

C++基礎知識點整理

基本語法 1、static關鍵字的作用 1、全局靜態變量 加了static關鍵字的全局變量只能在本文件中使用。 存儲在靜態存儲區&#xff0c;整個程序運行期間都存在。 2、局部靜態變量 作用域仍為局部作用域。 不過離開作用域之后&#xff0c;并沒有銷毀&#xff0c;而是貯存程序中&a…

Haskell學習筆記

《learn you a Haskell》這書的結構與常見的語言入門教材完全不一樣。事實上&#xff0c;即使學到第八章&#xff0c;你還是寫不出正常的程序…因為到現在為止還沒告訴你入口點模塊怎么寫&#xff0c;IO部分也留在了最后幾章才介紹。最重要的是&#xff0c;沒有系統的總結數據類…

組合問題 已知組合數_組合和問題

組合問題 已知組合數Description: 描述&#xff1a; This is a standard interview problem to make some combination of the numbers whose sum equals to a given number using backtracking. 這是一個標準的面試問題&#xff0c;它使用回溯功能將總和等于給定數字的數字進…

可變參數模板、右值引用帶來的移動語義完美轉發、lambda表達式的理解

可變參數模板 可變參數模板對參數進行了高度泛化&#xff0c;可以表示任意數目、任意類型的參數&#xff1a; 語法為&#xff1a;在class或者typename后面帶上省略號。 Template<class ... T> void func(T ... args) {// }T:模板參數包&#xff0c;args叫做函數參數包 …

BI-SqlServer

一.概述 SqlServer數據倉庫ETL組件 IntegrationServiceOLAP組件 AnalysisService報表 ReportingServiceMDX(查多維數據集用的)和DMX(查挖掘模型用的)。二.商業智能-Analysis Services 項目 構建挖掘模型1構建挖掘模型2構建挖掘模型3三.商業智能-SqlServerAnalysis-Asp.net WebS…

python 子圖大小_Python | 圖的大小

python 子圖大小In some cases, the automatic figure size generated by the matplotlib.pyplot is not visually good or there could be some non-acceptable ratio in the figure. So, rather than allowing a pyplot to decide the figure size, we can manually define t…

《設計模式整理》

目錄常見設計模式如何保證單例模式只有一個實例單例模式中的懶漢與餓漢模式OOP設計模式的五項原則單例模式中的懶漢加載&#xff0c;如果并發訪問該怎么做常見設計模式 單例模式&#xff1a; 單例模式主要解決了一個全局使用的類頻繁的創建和銷毀的問題。 單例模式下確保某一個…

JSON學習資料整理

1.什么是JSON JSON(JavaScript Object Notation) 是一種輕量級的數據交換格式。它基于JavaScript的一個子集。 JSON采用完全獨立于語言的文本格式&#xff0c;但是也使用了類似于C語言家族的習慣&#xff08;包括C, C, C#, Java, JavaScript, Perl, Python等&#xff09;。這些…

OSI七層模型及其數據的封裝和解封過程

OSI(Open System Interconnection)參考模型把網絡分為七層: 1.物理層(Physical Layer) 物理層主要傳輸原始的比特流,集線器(Hub)是本層的典型設備; 2.數據鏈路層(Data Link Layer) 數據鏈路層負責在兩個相鄰節點間無差錯的傳送以幀為單位的數據,本層的典型設備是交換機(Switch)…

rss聚合模式案例_RSS的完整形式是什么?

rss聚合模式案例RSS&#xff1a;真正簡單的聯合 (RSS: Really Simple Syndication) RSS is an abbreviation of Really Simple Syndication. It is also called Rich Site Summary. It is quality attainment for the syndication of collection of web content and used to di…

《MySQL——38道查詢練習(無連接查詢)》

目錄一、準備數據1、創建數據庫2、創建學生表3、創建教師表4、創建課程表5、創建成績表6、添加數據二、查詢練習1、查詢 student 表的所有行2、查詢 student 表中的 name、sex 和 class 字段的所有行3、查詢 teacher 表中不重復的 department 列4、查詢 score 表中成績在60-80之…

工作經常使用的SQL整理,實戰篇(一)

工作經常使用的SQL整理&#xff0c;實戰篇&#xff08;一&#xff09; 原文:工作經常使用的SQL整理&#xff0c;實戰篇&#xff08;一&#xff09;工作經常使用的SQL整理&#xff0c;實戰篇&#xff0c;地址一覽&#xff1a; 工作經常使用的SQL整理&#xff0c;實戰篇&#xff…

XPth和XSLT的一些簡單用法

&#xff08;目的在于讓大家知道有這個東西的存在&#xff09; XPath:即XML Path語言(Xpath)表達式使用路徑表示法(像在URL中使用一樣)來為XML文檔的各部分尋址&#xff01; 關于XPath如何使用了&#xff0c;我們來看看&#xff01;當然這里面的代碼只是入門&#xff0c;更深層…

isc dhcp_ISC的完整形式是什么?

isc dhcpISC&#xff1a;印度學校證書 (ISC: Indian School Certificate) ISC is an abbreviation of the Indian School Certificate. It alludes to the 12th class examination or higher secondary examination conducted by the Council for the Indian School Certificat…

《MySQL——連接查詢》

內連接&#xff1a; inner join 或者 join 外連接 1、左連接 left join 或 left outer join 2、右連接 right join 或 right outer join 3、完全外連接 full join 或 full outer join 圖示理解 全連接 創建person表和card表 CREATE DATABASE testJoin;CREATE TABLE person (…

win7下 apache2.2 +php5.4 環境搭建

這篇文章很好 沒法復制 把鏈接粘貼來http://www.360doc.com/content/13/0506/13/11495619_283349585.shtml# 現在能復制了&#xff1a; 把任何一篇你要復制、卻不讓復制的文章收藏入收藏夾(直接CtrlD,確定) 2在收藏夾中&#xff0c;右擊剛才收藏的那個網址&#xff0c;點屬性 3…

HDU_1533 Going Home(最優匹配) 解題報告

轉載請注明出自cxb:http://blog.csdn.net/cxb569262726 題目鏈接&#xff1a;http://acm.hdu.edu.cn/showproblem.php?pid1533 說實話&#xff0c;這個題目剛開始還真看不出是完備匹配下的最大權匹配&#xff08;當然&#xff0c;這個也可以用網絡流做。&#xff08;應該是添加…

c#中 uint_C#中的uint關鍵字

c#中 uintC&#xff03;uint關鍵字 (C# uint keyword) In C#, uint is a keyword which is used to declare a variable that can store an integral type of value (unsigned integer) the range of 0 to 4,294,967,295. uint keyword is an alias of System.UInt32. 在C&…