国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

HDU 3593 The most powerful force 樹狀dp

2019-11-11 06:21:55
字體:
供稿:網(wǎng)友

PRoblem: 有很多的士兵需要出征,如果士兵出征那他的上級也必須出征,如果一個(gè)士兵的上級是自己,那么說明自己就是老大,最多不超過500個(gè)老大,每個(gè)士兵有兩個(gè)屬性,需要花費(fèi)的錢和能貢獻(xiàn)的價(jià)值,給定允許消費(fèi)的最大的錢,問最多的貢獻(xiàn)是多少? Solution: 很明顯可以看到題目的數(shù)據(jù)結(jié)構(gòu)是一個(gè)森林,但是我們可以通過設(shè)置一個(gè)0節(jié)點(diǎn)當(dāng)做所有老大的父節(jié)點(diǎn),這樣就轉(zhuǎn)化為了一棵樹,這個(gè)問題很像一個(gè)背包問題,但有點(diǎn)區(qū)別,當(dāng)一個(gè)士兵是葉子時(shí),想一個(gè)物品一樣直接更新即可,但是如果它不是一個(gè)葉子,那么他還有很多的子節(jié)點(diǎn),這時(shí)在進(jìn)行其它兄弟節(jié)點(diǎn)dp時(shí),一開始的初始化已知最優(yōu)解就很關(guān)鍵了,也就是說每一個(gè)兄弟節(jié)點(diǎn)在動(dòng)規(guī)時(shí)都使用的是當(dāng)前子樹的最優(yōu)值,這就可以保證這棵子樹動(dòng)歸完成后是最優(yōu)解。可以理解為整個(gè)個(gè)動(dòng)態(tài)規(guī)劃就是利用每一棵子樹不斷的更新可以購買這棵子樹的解。

#include<cstdio>#include<iostream>#include<sstream>#include<cstdlib>#include<cmath>#include<cctype>#include<string>#include<cstring>#include<algorithm>#include<stack>#include<queue>#include<set>#include<unordered_set>#include<map>#include<unordered_map>#include<ctime>#include<vector>#include<fstream>#include<list>#include<numeric>#include<functional>using namespace std;typedef long long ll;typedef unsigned long long ull;#define ms(s) memset(s,0,sizeof(s))const double PI = 3.141592653589;const int INF = 0x3fffffff;int c[100010], v[100010];vector<int> Tree[100010];int dp[505][10010];int n, maxg;void solve(int root, int g) { for(int i = 0; i < Tree[root].size(); i++) { int child = Tree[root][i]; if(Tree[child].empty()) { for(int j = g; j >= c[child]; j--) { dp[root][j] = max(dp[root][j], dp[root][j-c[child]]+v[child]); } } else { for(int j = 0; j <= g-c[child]; j++) { dp[child][j] = dp[root][j]; } solve(child, g-c[child]); for(int j = g; j >= c[child]; j--) { dp[root][j] = max(dp[root][j], dp[child][j-c[child]]+v[child]); } } }}int main() {// freopen("/Users/really/Documents/code/input","r",stdin); // freopen("/Users/really/Documents/code/output","w",stdout); ios::sync_with_stdio(false); int fa; while(cin >> n >> maxg) { //init for(int i = 0; i <= 500; i++) Tree[i].clear(); ms(dp); for(int i = 1; i <= n; i++) { cin >> c[i] >> v[i] >> fa; if(fa == i) Tree[0].push_back(i); else Tree[fa].push_back(i); } solve(0, maxg); cout << dp[0][maxg] << endl; } return 0;}
發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 景洪市| 馆陶县| 平武县| 抚松县| 视频| 白山市| 封丘县| 顺义区| 上杭县| 张家界市| 阿鲁科尔沁旗| 海宁市| 广丰县| 宜都市| 宁海县| 永寿县| 绵竹市| 三门峡市| 巴中市| 黔西县| 金沙县| 石家庄市| 林芝县| 新河县| 四平市| 连平县| 石城县| 南川市| 视频| 夏河县| 武清区| 日喀则市| 桂东县| 城口县| 桐城市| 正宁县| 松原市| 穆棱市| 瑞昌市| 涪陵区| 阳西县|