最近幾天學了一下樹形\(dp\)
其實早就學過了 來提高一下開啟樹形\(dp\)的姿勢。
1、沒有上司的晚會
我的人生第一道樹形\(dp\),其實就是兩種情況:
\(dp[i][1]\)表示第i個人來時的最大人數
\(dp[i][0]\)表示第i個人不來時的最大人數
然後遞迴至葉子節點,倒推\(dp\)
狀態轉移方程:
\[dp[root][1]+=dp[g[root][i]][0];
\]\[dp[root][0]+=max(dp[g[root][i]][1],dp[g[root][i]][0]);
\]\(code\ below:\)
#pragma gcc optimize(2)
#include using namespace std;
int n;
int f[6010];
int dp[6010][2];
vectorg[6010];
//dp[i][1]表示第i個人來
//dp[i][0]表示第i個人不來
void dfs(int root)
t[maxn<<2];
int time;
void init(int now)
}int dfs(int x,int tot)
int main()
5、vacation
水題\(code\ below:\)
#include using namespace std;
const int maxn=50000+10;
int n,dp[maxn][2];
vectortree[maxn];
void dfs(int x,int fa)
e[maxn<<1];
inline void add(ll x,ll y,ll w)
void dfs(ll x,ll fa,ll dis)
}void solve(ll x,ll fa) }}
int main()
for(ll i=1;i7、barn painting
手動寫\(if\)判斷,然後統計\(dfs\)一下,記錄\(sum\),乘一下
#include #define ll long long
using namespace std;
const ll maxn=100000+10;
const ll p=1e9+7;
ll n,k,head[maxn],to[maxn<<1],nxt[maxn<<1],vis[maxn],tot,ans;ll dp[maxn][3];
inline void add(ll x,ll y)
ll dfs(ll x,ll col,ll fa)
return dp[x][col];
}int main()
for(ll i=1;i<=k;i++)
for(ll i=0;i<3;i++)
dfs(1,i,1);
for(ll i=0;i<3;i++)
ans=(ans+dp[1][i])%p;
printf("%lld\n",ans);
return 0;
}
樹形DP學習筆記
樹形dp就是.我也不知道是什麼,反正乙個主件下面有很多的附件可選就是樹形dp,咕咕咕 樹形dp的主要實現形式是dfs,在dfs中dp,主要的實現形式是dp i j,i是以i為根的子樹,j是表示在以i為根的子樹中選擇j個子節點,0表示這個節點不選,1表示選擇這個節點。有的時候j或0 1這一維可以壓掉 ...
樹形DP學習筆記
1.為什麼會有樹形dp 正常來說,線性dp用來解決序列的問題,但是當我們維護的資料結構發生變化的時候,比如,現在我們需要對一棵樹 進行dp,普通的線性dp邊無法解決了,這個時候,就需要用到樹形dp了 2.樹形dp的應用場景 1中的應用場景給的比較抽象,這裡詳細的來說一下。最經典的例子就是乙個等級森嚴...
樹形dp學習
練習專題參考 傳送門 hdu 1520 題意 給出n個點,然後給出n個點對應的歡樂值,然後給出n 1條邊,a b,表示b是a的直屬上級,現在舉行乙個patry,但是要求員工和他的直屬上級不能同時來,問來的人的歡樂值的最大和是多少 思路 首先明確這是一棵有向樹,dp i 0 1 代表第i個人來 不來的...