【每日一題】樹 (dp)
樹
https://ac.nowcoder.com/acm/problem/13611
Solution
因?yàn)槭菢?,所以保證任意兩點(diǎn)都可以到達(dá),所以可以選擇從一個(gè)葉子節(jié)點(diǎn)作為出發(fā)點(diǎn)思考,
表示這個(gè)葉子節(jié)點(diǎn)所在包含了 i 個(gè)節(jié)點(diǎn)的子圖染了 j 種顏色的方案。
考慮當(dāng)前取的顏色是否和前 次取的顏色一樣,就是兩種決策:
- 若取的顏色相同則:
- 若取的是新的顏色,則有
種新顏色可以選擇,則:
這樣的話就可以從一個(gè)葉子節(jié)點(diǎn)開始染色到把整棵樹染色。
最后累加 n 個(gè)點(diǎn)取 1~k 種顏色的方案即可。
Code
#include<bits/stdc++.h> #define ll long long #define fi first #define se second #define mp make_pair #define pb push_back #define inf 0x3f3f3f3f using namespace std; inline ll read(){ll s=0,w=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();} while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();return s*w;} void put1(){ puts("Yes") ;}void put2(){ puts("No") ;}void put3(){ puts("-1"); } const int manx=3e2+5; ll mod=1000000000+7; ll dp[manx][manx]; int main(){ ll n=read(),k=read(); dp[0][0]=1; for(int i=1;i<=n;i++) for(int j=1;j<=k;j++) dp[i][j]+=(dp[i-1][j-1]*(k-j+1)+dp[i-1][j]), dp[i][j]%=mod; ll ans=0; for(int i=1;i<=k;i++) ans+=dp[n][i],ans%=mod; cout<<ans; return 0; }