選課 洛谷p2014
阿新 • • 發佈:2018-11-02
題目描述
在大學裡每個學生,為了達到一定的學分,必須從很多課程裡選擇一些課程來學習,在課程裡有些課程必須在某些課程之前學習,如高等數學總是在其它課程之前學習。現在有N門功課,每門課有個學分,每門課有一門或沒有直接先修課(若課程a是課程b的先修課即只有學完了課程a,才能學習課程b)。一個學生要從這些課程裡選擇M門課程學習,問他能獲得的最大學分是多少?
輸入輸出格式
輸入格式:
第一行有兩個整數N,M用空格隔開。(1<=N<=300,1<=M<=300)
接下來的N行,第I+1行包含兩個整數ki和si, ki表示第I門課的直接先修課,si表示第I門課的學分。若ki=0表示沒有直接先修課(1<=ki<=N, 1<=si<=20)。
輸出格式:
只有一行,選M門課程的最大得分。
輸入輸出樣例
輸入樣例#1: 複製
7 4 2 2 0 1 0 4 2 1 7 1 7 6 2 2
輸出樣例#1: 複製
13
#include<bits/stdc++.h> #define f(i,l,r) for(i=(l);i<=(r);i++) #define ff(i,r,l) for(i=(r);i>=(l);i--) using namespace std; const int MAXN=305; struct Edge{ int v,w,nxt; }e[MAXN<<1]; int h[MAXN],tot,a[MAXN]; int n,m; int dp[MAXN][MAXN],size[MAXN]; inline void add(int u,int v) { e[tot].v=v; e[tot].nxt=h[u]; h[u]=tot++; } void dfs(int u,int fa) { int i,j,k; // cout<<u<<"GG"<<endl; dp[u][1]=a[u]; size[u]=1; for(i=h[u];~i;i=e[i].nxt){ int v=e[i].v; // cout<<v<<"GGG"<<endl; if(v==fa) continue; dfs(v,u); size[u]+=size[v]; ff(j,size[u],2){ f(k,1,j-1){ dp[u][j]=max(dp[u][j],dp[u][j-k]+dp[v][k]); } } } } int main() { ios::sync_with_stdio(false); memset(h,-1,sizeof(h)); int i,j,u,w; cin>>n>>m; f(i,1,n){ cin>>u>>a[i]; add(u,i); add(i,u); } dfs(0,-1); cout<<dp[0][m+1]<<endl; return 0; }