codeforces 285(Round #175)题解

A:直接写降序的即可,剩下全部升序

B:水模拟

C:排序+贪心即可

D:先弄一个初始排列a[i]=i,然后枚举排列使其满足要求,可以用stl的next_permutation函数,很方便。然后将a[i]=i这种排列对应的方案数*n!(1~n的排列为n!种,b数组随a对应改变即可)即可,n<=16打表即可

E:递推好题!

|p[i]-i|=1,意味着第i位置要是cool位置的话只能取i+1或者i-1,这点很重要。递推前两维很容易想,f[i][j]表示前i个位置有j个位置是cool位置,但是只有两维我们显然找不到递推公式。由于前面的重要结论,我们可以想到第三维,f[i][j][k]表示前i个位置有j个位置是cool位置,k是两个二进制位,表示第i+1和i是否已经被选,由此可以建立递推关系。然F(i) = Σ(f(n, i, k)) * (n - i)!但是注意,F[i]并不是仅仅i个cool位置的方案数,因为(n-i)!种包括了已经

有了i个cool位置的所有情况,显然,还可能包括更多的cool位置。注意到,F[n]必然是只有n个cool位置的方案数,我们可

以得到F[n-1],F[n-2]...。可以这样想,F[i],F[j](i<j)的关系。F[i]中重复计算了c[j][i]次f[j](c[j][i]为组

合数),(想一想,为什么)。减去重复计算的即可。

至于具体递推,详见代码

#include<cstdio>//DP f[i][j][k]表示前i个位置选了j个好位置k是两个二进制位表示i+1,i是否用过 
#include<iostream>
#include<algorithm>
#include<cmath> 
using namespace std;
const int N=1005;
long long c[N][N],f[N][N][4],F[N];
const int MOD=1000000007;
void add(long long &x,long long y)
{
    x=x+y;
    if(x>=MOD) x=x-MOD;
}
int main()
{
      int i,j,k,n,K; 
      scanf("%d%d",&n,&K);
      for(i=0;i<=n;++i)
       c[i][0]=1;
      for(i=1;i<=n;++i)
       for(j=1;j<=i;++j)
        c[i][j]=(c[i-1][j-1]+c[i-1][j])%MOD; 
      f[0][0][2]=1;  
      for(i=1;i<=n;++i)
       for(j=0;j<i;++j)
        for(k=0;k<=3;++k) 
        {
            if(k&1) add(f[i][j+1][(k>>1)+2],f[i-1][j][k]);
            if(i<n) add(f[i][j+1][k>>1],f[i-1][j][k]);
            add(f[i][j][(k>>1)+2],f[i-1][j][k]); 
        }  
      for(j=0;j<=n;++j) 
       {
         for(k=0;k<=3;++k)
          add(F[j],f[n][j][k]);
         for(k=1;k<=n-j;++k)
          F[j]=F[j]*k%MOD; 
       } 
      for(i=n-1;i>=0;--i)
       for(j=i+1;j<=n;++j)
        add(F[i],MOD-c[j][i]*F[j]%MOD);  
      printf("%d",F[K]);    
//      system("pause");
      return 0;  
}
      



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值