题意:给定s(1<=<=20),问能组成多少个长为s的数字串满足数字串先不降后不升。
题解:dp[ i ][ j ]表示形成 i 位长 以 j 数字结尾的不降的串的个数,然后枚举不降与不升的分界点(在该点一定是降,否则会算重)即可,最后加上全0的情况。
Sure原创,转载请注明出处。
#include <iostream>
#include <cstdio>
#include <memory.h>
using namespace std;
const int maxn = 22;
__int64 dp[maxn][maxn >> 1];
int n;
void init()
{
memset(dp,0,sizeof(dp));
for(int i=0;i<10;i++)
{
dp[1][i] = 1LL;
}
dp[0][0] = 1LL;
for(int i=2;i<=20;i++)
{
for(int j=0;j<10;j++)
{
for(int k=0;k<=j;k++)
{
dp[i][j] += dp[i-1][k];
}
}
}
return;
}
void solve()
{
__int64 ans = 1;
for(int i=0;i<=n;i++)
{
for(int j=0;j<=9;j++)
{
for(int k=0;k<j;k++)
{
ans += dp[i][j] * dp[n-i][k];
}
}
}
printf("%I64d\n",ans);
return;
}
int main()
{
init();
while(~scanf("%d",&n))
{
solve();
}
return 0;
}
本文介绍了一种使用动态规划解决特定数字串构造问题的方法。针对长度为s的数字串,探讨了如何确保数字串先不降后不升,并提供了一个有效的算法实现方案。

被折叠的 条评论
为什么被折叠?



