POJ 1155 TELE 樹形背包問題

來源:互聯網
上載者:User

標籤:blog   os   io   for   問題   cti   div   amp   

題目描述看的莫名其妙,很久才看懂。

就是很裸的樹形背包問題吧,狀態是dp(i,j)表示節點i取到j個客戶能得到的最大收益。

注意一開始初始化的時候所有j為0的時候應該是0,然後其他值都要初始化成負無窮,因為收益有可能是負值。

然後做01背包的時候注意方向,防止出現取某一個元素多次

#include <cstdio>#include <cstring>#include <iostream>#include <map>#include <set>#include <vector>#include <string>#include <queue>#include <deque>#include <bitset>#include <list>#include <cstdlib>#include <climits>#include <cmath>#include <ctime>#include <algorithm>using namespace std;#define MP make_pair#define PB push_backtypedef long long LL;typedef unsigned long long ULL;typedef vector<int> VI;typedef pair<int,int> pii;const int INF = INT_MAX / 3;const double eps = 1e-8;const LL LINF = 1e17;const double DINF = 1e60;const int maxn = 3000 + 5;//dp(i,j) 第i個節點找到j個客戶的最大收益int dp[maxn][maxn],N,M;int first[maxn],nxt[maxn],w[maxn],v[maxn],ecnt;int P[maxn],ccnt[maxn];void adde(int uu,int vv,int ww) {    w[ecnt] = ww; v[ecnt] = vv; nxt[ecnt] = first[uu]; first[uu] = ecnt++;}int getcnt(int now) {    if(first[now] == -1) return ccnt[now] = 1;    for(int i = first[now];~i;i = nxt[i]) {        ccnt[now] += getcnt(v[i]);    }    return ccnt[now];}void dfs(int now) {    //printf("now is %d\n",now);    if(first[now] == -1) {        //如果當前為葉子節點        dp[now][0] = 0; dp[now][1] = P[now];    }    else {        for(int i = first[now];~i;i = nxt[i]) {            dfs(v[i]);            //更新所有狀態,01背包            for(int j = ccnt[now];j >= 0;j--) {                //枚舉是從下一個節點拿幾個,這裡注意是01背包,從大到小更新                for(int k = 0;k <= ccnt[v[i]] && k <= j;k++) {                    dp[now][j] = max(dp[now][j],                            dp[v[i]][k] + dp[now][j - k] - w[i]);                    //printf("k is %d %d + %d - %d\n",k,dp[v[i]][k],dp[now][j - k],w[i]);                }                //printf("dp[%d][%d] = %d\n",now,j,dp[now][j]);            }        }    }}int main() {    while(scanf("%d%d",&N,&M) != EOF) {        memset(first,-1,sizeof(first));        memset(ccnt,0,sizeof(ccnt));        ecnt = 0;        for(int i = 1;i <= N - M;i++) {            int k; scanf("%d",&k);            for(int j = 1;j <= k;j++) {                int ak,ck; scanf("%d%d",&ak,&ck);                adde(i,ak,ck);            }        }        for(int i = N - M + 1;i <= N;i++) scanf("%d",&P[i]);        getcnt(1);        for(int i = 1;i <= N;i++) {            for(int j = 0;j <= ccnt[i];j++) dp[i][j] = -INF;            dp[i][0] = 0;        }        dfs(1);        int ans = 0;        for(int i = 0;i <= ccnt[1];i++) if(dp[1][i] >= 0) ans = i;        printf("%d\n",ans);    }    return 0;}

  

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.