题意:给定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; }