给出一段由‘+’和‘-’组成的符号,长度为n,问从1,2,3.....n的错排跟原数列相减后符号跟给出的字符串想匹配的有多少种。好拗口的题意,不知道怎么说好,长度少于20,太有误导性了,第一眼就以为是状态压缩,快结束才知道有1000个test,这数据出的太不科学了吧?
思路:dp[ i ][ j ],第i位的时候还有j个数没放好的数量,在每一个状态下都假设‘-’号的位置全部已经放好,那么对于i+1的时候,如果是’-‘号,那么必须在前面取一个数出来放进去,如果是’+‘号,这个数只能在后面的数放进来,处理下细节,搞掂。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <sstream>
#include <iostream>
#include <algorithm>
#include<cstdlib>
#include<queue>
using namespace std;
#define N 100005
#define L(x) x<<1
#define R(x) x<<1|1
#define M(x,y) (x + y)>>1
#define MOD 10007
#define MODD 1000000006
#define inf 0x7fffffff
#define llinf 0x7fffffffffffffff
#define LL long long
LL dp[25][25];
char s[25];
int main()
{
LL i,j,k,l;
while(cin>>s)
{
if(s[0] == '-')
{
puts("0");
continue;
}
memset(dp,0,sizeof(dp));
LL len = strlen(s);
dp[1][1] = 1;
for(i = 2;i <= len;i++)
{
if(s[i - 1] == '+')
{
for(j = 1;j <= len;j++)
{
dp[i][j] += dp[i - 1][j - 1];
dp[i][j] += dp[i - 1][j]*j;
}
}
else
{
for(j = 1;j <= len;j++)
{
dp[i][j - 1] += dp[i - 1][j]*j*j;
dp[i][j] += dp[i - 1][j]*j;
}
}
}
cout<<dp[len][0]<<endl;
}
return 0;
}