P3647 APIO2014 連珠線 換根DP

2022-06-13 21:06:12 字數 1133 閱讀 2633

傳送門

我們通過分析+手動模擬能夠發現,藍線的形態只有兩種:\(son[u][1]-u-son[u][2]\)和\(son[u]-u-fa[u]\)對於每乙個節點,要麼是乙個藍線的中點,要麼就是藍線的端點,所以我們設\(f[u][0]\)表示\(u\)為藍線端點時的答案,\(f[u][1]\)表示\(u\)作為中點時的答案

轉移方程如下:

\(f[u][0]=max(f[v][0],f[v][1]+w_i)\)表示\(u\)和\(v\)之間連紅線和連藍線兩種情況

\(f[u][1]=f[u][0]+max(f[v][0]+w_i-max(f[v][0],f[v][1]+w_i))\)表示在\(f[u][0]\)的情況下再選擇乙個兒子連藍線

然後我們要通過換根來統計不同情況下的答案,那麼我們考慮換根時可能造成的影響,首先乙個點的兒子變成父親後,對自己的貢獻消失了,也就是說轉移時的最大值可能沒有了,所以我們要記錄次大值,然後這個點還要對自己的兒子產生新的貢獻,所以我們記\(dp[u][1/0][i]\)表示在\(f[u][1/0]\)的情況下不考慮第\(i\)個兒子的答案,換根時要先處理出父親的正確貢獻後才能遞迴到兒子

#include#define p(x)  f[x][0]+e[i].val-max(f[x][0],f[x][1]+len[x])

using namespace std;

namespace zzc

e[maxn<<1];

void add(int u,int v,int w)

void dfs(int u,int ff)

f[u][1]=f[u][0]+mx1;

for(int i=head[u];i;i=e[i].nxt)

else

} }

void solve(int u)

ans=max(ans,f[son[u][i]][0]+max(f[u][0],f[u][1]+len[son[u][i]]));

solve(son[u][i]);

} }void work()

dfs(1,0);

solve(1);

printf("%d\n",ans); }}

int main()

P3648 APIO2014 序列分割

part1 首先看到題目,嗯 o o很騷 手玩一波樣例之後發現狀態很好想 這裡簡單地任務階段可以被劃分次數 也就是劃分順序 和劃分位置來劃分 初步想法是 f i j 表示前 i 次最後一次切的是 j 位置 隨後意識到沒法通過上一層進行轉移,這裡出現問題也是正常,因為沒有進行更深入地發掘性質 此處無法...

P3648 APIO2014 序列分割

傳送門 首先容易證明,得分和切的順序沒有關係 所以直接預設先切左邊再切右邊就好了 然後顯然可以 dp 一開始想的是設 f i j 表示切了 i 次,此次把 j 和 j 1 分開,得到的最大價值 那麼顯然列舉上一次切的位置 k 那麼 f i j f i 1 k sum j sum k sum n su...

序列分割 Apio2014

time limit 40 sec memory limit 128 mb submit 4036 solved 1574 submit status discuss 小h最近迷上了乙個分隔序列的遊戲。在這個遊戲裡,小h需要將乙個長度為n的非負整數序列分割成k 1個非空的子串行。為了得到k 1個子序...