cf 414B Mashmokh and ACM 动态规划
題目鏈接:http://codeforces.com/problemset/problem/414/B
?
dp[i][j]表示長(zhǎng)度為i、最后一個(gè)數(shù)字為j的合法序列總數(shù)
dp[1][1...2000]都是1
后面用dp[i-1][j] 去更新 dp[i][j*t] (1 <= j*t <= 2000) 即用因子去更新它的倍數(shù)
表面上看是2000^3的復(fù)雜度會(huì)爆 其實(shí)不用算那么多次
最外層循環(huán)是2000
分析第二層和第三層 需要算 2000/1 + 2000/2 + 2000/3 + 2000/4 + ... + 2000/2000 次
即2000 * (1/1 + 1/2 + 1/3 + ... + 1/2000)
后面的括號(hào)是一個(gè)【調(diào)和級(jí)數(shù)】 利用高等數(shù)學(xué)知識(shí)可知 它是有上限的 為自然對(duì)數(shù)e
所以本算法的時(shí)間復(fù)雜度實(shí)際上僅為 e*2000*2000?
綽綽有余
?
因?yàn)橄聵?biāo)從1開(kāi)始計(jì)數(shù)
然后一開(kāi)始fill的時(shí)候沒(méi)注意看wa了幾炮T^T
?
#include <cstdio> #include <cstdlib> #include <ctime> #include <iostream> #include <cmath> #include <cstring> #include <algorithm> #include <stack> #include <set> #include <queue> #include <vector>using namespace std;const int maxn = 2010; const int M = 1000000007;int dp[maxn][maxn];int main() {//freopen("in.txt", "r", stdin);int n, k;scanf("%d%d", &n, &k);fill(dp[1] + 1, dp[1] + 2001, 1);for(int i = 2; i <= k; i++){for(int j = 1; j <= 2000; j++){for(int t = 1; j*t <= 2000; t++){dp[i][j*t] = (dp[i][j*t] + dp[i-1][j]) % M;}}}int ans = 0;for(int i = 1; i <= n; i++)ans = (ans + dp[k][i]) % M;printf("%d\n", ans);return 0; }
?
轉(zhuǎn)載于:https://www.cnblogs.com/dishu/p/4295089.html
總結(jié)
以上是生活随笔為你收集整理的cf 414B Mashmokh and ACM 动态规划的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 小米换屏幕多少钱啊?
- 下一篇: BZOJ 3573 米特运输