題目意思太羅嗦,不解釋了。這道題一開始一直segmentation fault,問了秦總才發現可能是陣列放在dfs裡面的關心後來又wa了無數次,結果是因為它居然可以是個森林!!!簡直報警了,題目中明明說的是koopa的所有兒子,居然還可以存在森林。唉。。。
這道題好事蠻不錯的一道題,每一個點有三種狀態:dp[i][0],dp[i][1],dp[i][2]。dp[i][1]代表第i個人剛剛被幹掉,第i個節點及其子樹的最大值。dp[i][0]代表第i個節點即所有節點的t[i]值之和。dp[i][2]代表的是第i個節點沒有被幹掉所能幹掉其子樹的最大值和。
下面來寫轉移方程:
dp[u][0] = t[u] + sum;
dp[u][2] = max = max+ sum; 這兩個v相互獨立
dp[u][1] = max + sum;
注意下一邊界條件就可以開始寫了。。。算 dp[v][0]-dp[v][2]+dp[w][1]-dp[w][2]的最大值的時候有一個小技巧,直接看我的**:
#include #include #include #include #include #define for(i,x,y) for(int i = x;i < y;i ++)using namespace std;
const int maxn = 2222;
int n,dp[maxn][3],t[maxn],head[maxn],edge_cnt; //dp[i][0]表示i個節點和他的所有子樹都被殺了,dp[i][1]表示第一次i個節點被殺了,dp[i][2]表示i個節點沒被殺
int st[maxn];
struct edgeedge[maxn<<1];
bool cmp(int x,int y)
void add_edge(int u,int v)
void dfs(int u,int fa)
else dp01 = max(dp01,t[v]);
if(dp[v][1]-dp[v][2] >= dp10)
else dp11 = max(dp11,dp[v][1]-dp[v][2]);
dp2 = max(dp2,dp[v][0]-dp[v][2]+dp[v][1]-dp[v][2]);
cnt++;
}if(!cnt) return;
if(cnt == 1)
else
else
dp[u][1] += sum + dp00 + dp10;
dp[u][2] += sum+dp00;
}return;
}int dfs2(int u,int fa)
return ans;
}int main()
add_edge(i,to);
add_edge(to,i);
}int ans = 0;
for(i,0,st_cnt-1) ans += dfs2(st[i],-1);
dfs(n-1,-1);
printf("%d\n",ans+dp[n-1][1]);
}return 0;
}
ZOJ 1276 DP
給出一系列的1x2的矩陣,要你求出矩陣以什麼樣的次序相乘才使得相乘次數最少,。 不用排序,只要決定該矩陣是和前面相乘比較好,還是後面 。 今天仔細想了一下,跟之前做的dp題目做了下對比,你比如說猴子堆磚塊拿香蕉那題,那種是通過設定區域性量j 求得1到j的區域性最優解,再遞增j,直到求得全域性最優解 這種題...
ZOJ 3463 Piano dp
題目意思好毒瘤 很容易想到 dp 狀態 dp i j k 表示列舉到第 i 個位置,左大拇指在 j ,右大拇指在 k 的最少代價 對於每一個按鍵,直接列舉用哪個手去覆蓋即可 但是題目那個手不能覆蓋怎麼處理? 其實並不需要考慮,這種情況一定會被一種同樣優秀的方法替代掉 include include ...
ZOJ 3640 概率DP
題意 給定初始值為f 等概率相遇n種怪物 其相應值的c i 若當前值大於c i 達成的天數為t i 否則花一天升級c i 再t i 達成,求達成期望 注意到過程是逆序單調的 先初始化limit再倒過來遞推即可 include include include include include inclu...