Apple Tree POJ - 2486

來源:互聯網
上載者:User

標籤:blog   超過   using   並且   eof   數組   href   hive   for   

Apple Tree POJ - 2486

題目大意:一棵點帶權有根樹,根節點為1。從根節點出發,走k步,求能收集的最大權值和。

樹形dp。複雜度可能是O(玄學),不會超過$O(nk^2)$。(反正這題不卡這個,考思想)參考

ans[i][j][0]表示i點以下共走j步,不回來,可能收集到最大的權值
ans[i][j][1]表示i點以下共走j步,回來,可能收集到最大的權值

比較複雜的是,每個節點(以下稱當前節點)從其子節點轉移的時候,需要用一個背包:

t[i][j][0]表示當前節點的前i個子節點共走j步,不回來
t[i][j][1]表示當前節點的前i個子節點共走j步,回來

對於t[i][j][0],要麼是當前節點的前i-1個子節點共走j步(包括去和回來前面的子節點所用步數),在之前就不回來;

要麼是前i-1個子節點共走j-p步(包括去和回來前面的子節點所用步數),當前節點走到第i個子節點用1步,第i個子節點向下走p-1步,不回來;

要麼是花一步走到第i個子節點,在第i個子節點往下走p-2步,再花一步走回當前節點,再在前i-1個子節點中走j-p步(包括去和回來前面的子節點所用步數)並且不回來。

因此t[i][j][0]=max(t[i-1][j][0],max{t[i-1][j-p][1]+ans[nowson][p-1][0]},max{t[i-1][j-p][0]+ans[nowson][p-2][1]})

對於t[i][j][1],要麼是前i-1個子節點共走j-p步(包括去和回來前面的子節點所用步數),走到第i個子節點花1步,第i個子節點向下走用p-2步並回來,從第i個子節點回來花一步;要麼是前i-1個子節點共走j步(包括去和回來前面的子節點所用步數),回來。

因此t[i][j][1]=max(t[i-1][j][1],max{t[i-1][j-p][1]+ans[nowson][p-2][1]})

當然實際求解的時候並不需要每個節點開一個t數組,只需要在ans數組上直接做就行了。就是先對t數組求解過程用滾動數組最佳化,那麼只需要兩維t[j][0/1]。這時只需要把ans[當前節點]的數組當做t去做就行了。另外,求解t數組的邊界要注意一下。另外,t數組再求解前就全部初始化成當前節點權值就行了。

最終答案很顯然:max(ans[1][k][0],ans[1][k][1])。

曾經錯誤:

naive的轉移方程:

t[i][j][0]=max(t[i-1][j][0],t[i-1][j-p][0],t[i-1][j-p][1]+ans[son][p][0])
t[i][j][1]=max(t[i-1][j][1],t[i-1][j-p][1]+ans[son][p][1])

事實上,這道題轉移t[i][j][0]的第3種(標紅的)情況很容易遺漏。另外,很容易忽略走去與走回子節點花費的1或2步。

 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 struct Edge 6 { 7     int to,next; 8 }edge[210]; 9 int ne,ans[110][210][2],f1[110];10 int a[110];11 int n,k;12 bool vis[110];13 void dfs(int u)14 {15     int j,kk=f1[u],p,v;16     vis[u]=true;17     for(j=0;j<=k;j++)18         ans[u][j][0]=ans[u][j][1]=a[u];19     while(kk!=0)20     {21         v=edge[kk].to;22         if(!vis[v])23         {24             dfs(v);25             for(j=k;j>=0;j--)26             {27                 for(p=1;p<=j;p++)28                     ans[u][j][0]=max(ans[u][j][0],max(ans[u][j-p][0]+ans[v][p-2][1],ans[u][j-p][1]+ans[v][p-1][0]));29                 for(p=2;p<=j;p++)30                     ans[u][j][1]=max(ans[u][j][1],ans[u][j-p][1]+ans[v][p-2][1]);31             }32         }33         kk=edge[kk].next;34     }35 }36 int main()37 {38     int i,ta,tb;39     while(scanf("%d%d",&n,&k)==2)40     {41         ne=0;42         memset(ans,0,sizeof(ans));43         memset(vis,0,sizeof(vis));44         memset(f1,0,sizeof(f1));45         for(i=1;i<=n;i++)46             scanf("%d",&a[i]);47         for(i=1;i<n;i++)48         {49             scanf("%d%d",&ta,&tb);50             edge[++ne].to=tb;51             edge[ne].next=f1[ta];52             f1[ta]=ne;53             edge[++ne].to=ta;54             edge[ne].next=f1[tb];55             f1[tb]=ne;56         }57         dfs(1);58         printf("%d\n",max(ans[1][k][0],ans[1][k][1]));59     }60     return 0;61 }

Apple Tree POJ - 2486

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.