zoukankan      html  css  js  c++  java
  • [HDU4689]Derangement

    https://zybuluo.com/ysner/note/1232641

    题面

    给出(b_1,b_2,...,b_nin{−1,1}),求满足((p_i−i)*b_i<0)({1,2,...,n})的排列(p_i)的数量。

    • (nleq20)

    解析

    一开始并不知道这状态怎么设
    (f[i][j])表示当前填到了第(i)个位置,有(j)(b_i>0)(即(+)号)不满足。
    则可顺利写出决策:

    • 当前位置是(+)
      1、用当前的(i)填掉前面的一个空,有(j)种选择。
      2、该位不填,留到后面用。
    • 当前位置是(-):(必须用掉)
      1、用当前的(i)填掉前面的一个空,有(j)种选择。
      2、替代前面一个(+)号,再从前面的(+)号中选一个填在这里,均有(j)种选择。

    这种“延时(DP)”我似乎只会用它来计数。

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #define re register
    #define il inline
    #define ll long long
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    #define fp(i,a,b) for(re int i=a;i<=b;i++)
    #define fq(i,a,b) for(re int i=a;i>=b;i--)
    using namespace std;
    char s[25];
    ll n,f[25][25];
    il ll gi()
    {
      re ll x=0,t=1;
      re char ch=getchar();
      while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
      if(ch=='-') t=-1,ch=getchar();
      while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
      return x*t;
    }
    int main()
    {
      while(scanf("%s",s+1)!=EOF)
        {
          n=strlen(s+1);memset(f,0,sizeof(f));
          f[0][0]=1;
          fp(i,1,n)
    	{
    	  if(s[i]=='+')
    	    fp(j,1,i)
    	      f[i][j]+=f[i-1][j-1]+f[i-1][j]*j;
    	  else
    	    fp(j,0,i)
    	    {
    	      f[i][j]+=f[i-1][j]*j+f[i-1][j+1]*(j+1)*(j+1);
    	    }
    	}
          printf("%lld
    ",f[n][0]);
        }
      return 0;
    }
    
    
  • 相关阅读:
    【Splay树】
    毕业设计每日总结2020/2/8
    毕业设计每日总结2020/2/7
    毕业设计每日总结2020/2/6
    毕业设计每日总结2020/2/5
    毕业设计每日总结2020/2/4
    毕业设计每日总结2020/2/3
    毕业设计每日总结2020/2/2
    毕业设计每日总结2020/2/1
    毕业设计第一周计划
  • 原文地址:https://www.cnblogs.com/yanshannan/p/9393695.html
Copyright © 2011-2022 走看看