太精妙,留著以後慢慢消化
法一:我們一層一層地來推,列舉層數,然後再列舉這一層選擇的奶牛的個數(必須是偶數個的,因為我第一層已經處理好了),然後再列舉上一層選擇的奶牛的個數(也必須是偶數的,因為我把第二層也特殊處理了,就可以從第三層開始了),但是發現一共要選擇n個奶牛,所以不得不再加一維目前總共選擇的奶牛的數量,也就是加一層迴圈來列舉v罷了;現在就是重點!!!假設上一層選擇了m只奶牛,這一層選擇了j只奶牛,那麼m必須滿足m>=j/2(因為二叉樹的性質),假設上一層的狀態為f[i-1][m][v-j],也就是i-1層選擇了m只奶牛,前i-1層總共選擇了v-j只奶牛的方案總數,這時第i層就是選擇了j只奶牛了,第i層的j只奶牛和第i-1層的m只奶牛互相找媽媽,那麼可以選擇的方案總數就是c(m,j/2)*f[i-1][m][v-j],最後再統計就可以了。
#includeusing namespace std;
typedef long long ll;
typedef pairp;
#define inf 0xf3f3f3f
const int max=int(1000+10);
const int mol=9901;
int n,k,dp[100+10][200+10][200+10],w[200+10][200+10];
int main()
return 0;
}
法二:
採用記憶化搜尋來解決這道題。
我們規定左子樹必須正好滿足要求,即左子樹高度為y-1,而右子樹高度小於等於y-1(如果左右子樹高度不等,則左右子樹可以互換,方案乘以2)然後我們用兩個for迴圈分別列舉左子樹的節點數與右子樹的高度值(小於等於y-1),利用乘法原理狀態轉移。
#includeusing namespace std;
typedef long long ll;
typedef pairp;
#define inf 0xf3f3f3f
const int max=int(1000+10);
#define mod 9901
bool bvis[212][112];
int dp[212][112];
int n, m;
int dfs(int cnt, int height)}}
return state;
}int main()
Luogu P1472奶牛家譜(DP)
題目鏈結 這是一道考思維的好題。一開始設f i j 是i個點剛好j層的方案數,死活調不出來,看題解發現可以改為 j層的方案數,最後輸出f n m f n m 1 就好了。對於計算考慮左右子樹分配,設i個點分給左子樹,j個點分配右子樹,注意列舉順序,乘法原理搞一搞就好。我拼盡全力只得了57分,qwq。...
USACO TRAINING 奶牛家譜
時間限制 1 sec 記憶體限制 64 mb 提交 53 解決 24 提交 狀態 我的提交 農民約翰準備購買一群新奶牛。在這個新的奶牛群中,每乙個母親奶牛都生兩小奶牛。這些奶牛間的關係可以用二叉樹來表示。這些二叉樹總共有n個節點 3 n 200 這些二叉樹有如下性質 有多少不同的家譜結構?如果乙個家...
dp 奶牛家譜 Cow Pedigrees
令人窒息的奶牛題 農民約翰準備購買一群新奶牛。在這個新的奶牛群中,每乙個母親奶牛都生兩個小奶牛。這些奶牛間的關係可以用二叉樹來表示。這些二叉樹總共有n個節點 3 n 200 這些二叉樹有如下性質 每乙個節點的度是0或2。度是這個節點的孩子的數目。樹的高度等於k 1 k 100 高度是從根到最遠的那個...