TYVJ P1051 选课 Label:多叉转二叉树形dp(虐心♥)
生活随笔
收集整理的這篇文章主要介紹了
TYVJ P1051 选课 Label:多叉转二叉树形dp(虐心♥)
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
描述
學(xué)校實(shí)行學(xué)分制。每門的必修課都有固定的學(xué)分,同時(shí)還必須獲得相應(yīng)的選修課程學(xué)分。學(xué)校開設(shè)了N(N<300)門的選修課程,每個(gè)學(xué)生可選課程的數(shù)量M是給定的。學(xué)生選修了這M門課并考核通過就能獲得相應(yīng)的學(xué)分。?在選修課程中,有些課程可以直接選修,有些課程需要一定的基礎(chǔ)知識,必須在選了其它的一些課程的基礎(chǔ)上才能選修。例如《Frontpage》必須在選修了《Windows操作基礎(chǔ)》之后才能選修。我們稱《Windows操作基礎(chǔ)》是《Frontpage》的先修課。每門課的直接先修課最多只有一門。兩門課也可能存在相同的先修課。每門課都有一個(gè)課號,依次為1,2,3,…。?
表中1是2的先修課,2是3、4的先修課。如果要選3,那么1和2都一定已被選修過。? 你的任務(wù)是為自己確定一個(gè)選課方案,使得你能得到的學(xué)分最多,并且必須滿足先修課優(yōu)先的原則。假定課程之間不存在時(shí)間上的沖突。
輸入格式
輸入文件的第一行包括兩個(gè)整數(shù)N、M(中間用一個(gè)空格隔開)其中1≤N≤300,1≤M≤N。?以下N行每行代表一門課。課號依次為1,2,…,N。每行有兩個(gè)數(shù)(用一個(gè)空格隔開),第一個(gè)數(shù)為這門課先修課的課號(若不存在先修課則該項(xiàng)為0),第二個(gè)數(shù)為這門課的學(xué)分。學(xué)分是不超過10的正整數(shù)。??
?
輸出格式
輸出文件只有一個(gè)數(shù),實(shí)際所選課程的學(xué)分總數(shù)。測試樣例1
輸入
7 4?2 2?
0 1?
0 4?
2 1?
7 1?
7 6?
2 2
輸出
13代碼
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; struct cc{int l,r;}a[305];int N,M,f[305][305],v[305];void insert(int x,int i){//左兒子右兄弟,多叉轉(zhuǎn)二叉 if(a[x].l==0) a[x].l=i;else{int p=a[x].l;while(a[p].r!=0) p=a[p].r;a[p].r=i;}return; }void dp(int node,int k){if (k<=0) { f[x][k]=0; return; }//保證程序魯棒性,不寫也可以 if(f[node][k]!=0) return;if(a[node].r!=0) dp(a[node].r,k);//有兄弟 找兄弟f[node][k]=f[a[node].r][k];//不選兒子 只選兄弟 的時(shí)候 的最大值//沒兄弟的話 初始化時(shí)已經(jīng)為0 for(int i=0;i<k;i++){if(a[node].l!=0) dp(a[node].l,i);if(a[node].r!=0) dp(a[node].r,k-i-1);f[node][k]=max( f[node][k] , f[a[node].l][i]
+ f[a[node].r][k-i-1] + v[node]);} }int main(){ // freopen("01.txt","r",stdin);scanf("%d%d",&N,&M);for(int i=1;i<=N;i++){int x;scanf("%d%d",&x,&v[i]);insert(x,i);}dp(0,M+1);printf("%d\n",f[0][M+1]);return 0; }
網(wǎng)上的代碼 都沒注釋,都沒注釋,都沒注釋!!! (重要的事情說三遍!!!)
同樣耗了我很久看懂代碼
看來老夫還是要做第一個(gè)吃螃蟹的人
?
f[i][j]表示i節(jié)點(diǎn)選j節(jié)課的最大值
因?yàn)?節(jié)點(diǎn)不能選,所以 以下有+1操作//類似多源點(diǎn)和多匯點(diǎn)的最大流問題把
dp(0,M+1); printf("%d\n",f[0][M+1]);?
insert函數(shù)在左邊插入兒子,右邊插入兄弟,這里不懂的話 一定要請教度娘!!!(關(guān)鍵字“多叉轉(zhuǎn)二叉”)
還有insert函數(shù)請自行模擬一遍,謝謝合作
現(xiàn)在明白為什么他們不愛寫注釋了,這篇要么對他們太簡單,太么太長、
純手打,滿意請點(diǎn)贊~
轉(zhuǎn)載于:https://www.cnblogs.com/radiumlrb/p/5790586.html
總結(jié)
以上是生活随笔為你收集整理的TYVJ P1051 选课 Label:多叉转二叉树形dp(虐心♥)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Random随机数相关工具类
- 下一篇: 李洪强漫谈iOS开发[C语言-038]-