loj10154. 「一本通 5.2 例 2」选课

思路:
  树形背包DP

#include<cstdio>
#include<iostream>
#include<string>
#include<queue>
#include<cstring>
using namespace std;
const int maxn = 110;
void qread(int &x){
    x = 0;
    register int ch = getchar();
    while(ch < '0' || ch > '9')    ch = getchar();
    while(ch >= '0' && ch <= '9')    x = 10 * x + ch - 48, ch = getchar();
}
int n, m;
int head[maxn];
int go[maxn << 1];
int nxt[maxn << 1];

int wor[maxn];

int dp[maxn][maxn];
void init(){
    qread(m);
    qread(n);
    for(int i=1; i<=m; ++i){
        int x;
        qread(x), qread(wor[i]);
        go[i] = i;
        nxt[i] = head[x];
        head[x] = i;
    }
    memset(dp, 0xcf, sizeof(dp));
}
void DP(int x){
    dp[x][0] = 0;
    for(register int i = head[x]; i; i = nxt[i]){
        DP(go[i]);
        for(int t = m; t >= 0; --t){
            for(int j = t; j >= 0; --j)
                if(t - j >= 0)
                    dp[x][t] = max(dp[x][t], dp[x][t - j] + dp[go[i]][j]);
        }
    }
    if(x != 0)
        for(int t = m; t > 0; --t)
            dp[x][t] = dp[x][t - 1] + wor[x];    
}
int main(void){
    init();
    DP(0);
    cout << dp[0][n] << endl;
}

猜你喜欢

转载自www.cnblogs.com/junk-yao-blog/p/9491315.html