動態規劃 遞推

2021-08-29 03:52:03 字數 3646 閱讀 2166

hdu2044

1到n的路徑數f[n]有兩種**,f[n-1]的路徑,f[n-2]的路徑

編號a到b的蜂房可以看作編號1到b-a的蜂房

#include using namespace std;

long long f[55];

int n;

int main()

int a, b;

cin >> n;

while(n--)

return 0;

}

hdu2045

f[n]為n長度有多少種塗法,此時第n個位置與第1個位置顏色已經不同,來看第n-1個位置,若也與第1個位置不同,即f[n-1]種;若與第1個位置相同,則第n-2個位置肯定與第1個位置不同,可以塗其他兩種顏色,即f[n-2]*2

#include using namespace std;

long long f[55];

int main()

int n;

while(cin >> n)

return 0;

}

hdu2046

用f[i]表示2xi的方格鋪滿骨牌的方案數,那麼考慮第i列,要麼豎著放置乙個骨牌;要麼連同i-1列,橫著放置兩個骨牌,如圖2所示。由於骨牌的長度為1x2,所以在第i列放置的骨牌無法影響到第i-2列。很顯然,兩塊黑色的部分分別表示f[i-1]和f[i-2],所以可以得到遞推式f[i] = f[i-1] + f[i-2] (i >= 2),並且邊界條件f[0] = f[1] = 1。

首先可以明確當n等於奇數的時候,方案數一定為0。所以如果用f[i] (i 為偶數) 表示3xi的方格鋪滿骨牌的方案數,f[i]的方案數不可能由f[i-1]遞推而來。那麼我們猜想f[i]和f[i-2]一定是有關係的,如圖一 -1-3所示,我們把第i列和第i-1列用1x2的骨牌填滿後,輕易轉化成了f[i-2]的問題,那是不是代表f[i] = 3*f[i-2]呢?

仔細想想才發現不對,原因是我們少考慮了情況,這些情況用上圖情況無法表示,再填充完黑色區域後,發現和f[i-4]也有關係,但是還是漏掉了一些情況。

當一維的狀態已經無法滿足我們的需求時,我們可以試著增加一維,用二維來表示狀態,用f[i][j]表示(3 x i) + j個多餘塊的擺放方案數

轉化成二維後,我們可以輕易寫出三種情況的遞推式。

f[i][0] = f[i-2][0] + f[i-1][1] + f[i-2][2]

f[i][1] = f[i-1][2]

f[i][2] = f[i][0] + f[i-1][1]

邊界條件 f[0][0] = f[1][1] = f[0][2] = 1

f[n]表示n長度序列的塗法,若位置n為e或f,則n-1序列塗法為f[n-1],共f[n-1]*2種;若位置n為o,則位置n-1肯定為e或f,則n-2序列塗法為f[n-2],共f[n-2]*2種。

#include using namespace std;

long long f[45];

int main()

int n;

while(cin >> n)

return 0;

}

hdu2048

全錯排列

記f[n]為數量n的全錯排列數

假設正確排列是a對a,b對b…

若a和b匹配了,b也和a匹配了,則剩下的錯排數為f[n-2];

若a和b匹配了,b沒和a匹配,錯排數字f[n-1];

因為a還可以與其他n-1個匹配,f[n] = (n-1) * (f[n-1] + f[n-2])

#include #include using namespace std;

long long f[20];

int main()

return 0;

}

hdu2049

先從n個選出m個,再錯排

#include #include using namespace std;

long long f[20];//錯排

long long b[20];//階乘,求c(n, m)

int main()

scanf("%d", &t);

while (t--)

return 0;

}

hdu2050

先分析下直線分割平面的情況,增加第n條直線的時候,跟之前的直線最多有n-1個交點,此時分出的部分多出了(n-1)+1;

折線也是同理,f(1)=2,f(2)=7,先畫好前面n-1條折線,當增加第n條折線時,此時與圖形新的交點最多有2 * 2 * (n-1)個,所以分出的部分多出了2 * 2 * (n-1)+1個面,所以推出f(n)=f(n-1)+4 * (n-1)+1,n>=3

#include using namespace std;

int main()

cin >> t;

while(t--)

return 0;

}

poj1664

m個蘋果放n個盤子裡,若用dp[i][j]來表示i個蘋果放到j個盤子裡的方法數,可分為兩種情況:

ii>j 蘋果多,但題目允許有空盤子,則此時又分為有無空盤子,有時dp[i][j] = dp[i][j - 1],沒有時可以從每個盤子中拿出乙個蘋果,即變為向 i - j 個盤子中放 j 個蘋果,直到有空盤子為止,dp[i][j] = dp[i - j][j],總方法數就是兩者相加

#include #include #include using namespace std;

const int maxn = 15;

int dp[maxn][maxn];

int m, n;

int main()}}

cout << dp[m][n] << endl;

}return 0;

}

遞迴 遞推 動態規劃

問題一 已知f 1 1 f 2 1 且f n f n 1 f n 2 則f n 等於多少?解法一 遞迴 找到遞迴關係和遞迴出口 include using namespace std int n int sum int i int main 解法二 遞推 include using namespac...

判斷整除 動態規劃,遞推

總時間限制 1000ms 記憶體限制 65536kb 描述 乙個給定的正整數序列,在每個數之前都插入 號或 號後計算它們的和。比如序列 1 2 4共有8種可能的序列 1 2 4 7 1 2 4 1 1 2 4 3 1 2 4 5 1 2 4 5 1 2 4 3 1 2 4 1 1 2 4 7 所有結...

動態規劃 遞推 中國象棋

中國象棋 總時間限制 10000ms 單個測試點時間限制 1000ms 記憶體限制 65536kb 描述 在n行m列的棋盤上,放若干個炮可以是0個,使得沒有任何乙個炮可以攻擊另乙個炮。請問有多少種放置方法?中國象棋中炮的行走方式大家應該很清楚吧。輸入 一行包含兩個整數n,m,中間用空格分開。輸出 輸...