CF 285D & 285E

大家好,时隔一年,我复活了!

这两题并没有什么关系,只是一起A掉了就顺便一起写个题解吧……


CF 285D

打表

看了好久没有什么想法,猜测答案不会太大就直接打表。
发现n为偶数答案就是0。
n为13可以秒出,n为15大概等一会儿就好了,恩然后就过了。
打表代码不小心删了,反正不难写吧。


CF 285E

计数DP

第一反应记f[i][j][k][0/1][0/1]表示1~i已经填进去,且此时恰有j个位置满足good position,k表示下标大于i+1的位置有多少数,后面两个0/1表示i+1和i+2位置有没有数。因为下标大于i+1的数对i没有影响,所以每一个位置有数字的概率都是相等的,这样乘上一个分数就能知道i+2有数字的方案数。转移就是枚举i+1放哪里,这样且不论是不是对的,已经是三方的了。

发现有个k很难受,考虑优化掉它。之所以要记k,是因为不满足good position的数放在后面是有后效性的。要免去k,就干脆不放这些数,最后乘上阶乘表示随便放。那么这样就不能保证恰好j个位置满足,然而我们发现这样就能使用容斥了。观察发现对于状态中的j个good,一个实际上有m个good的方案会被算C(m,l)。那就直接容斥吧。

#include<cstdio>
#define N 1005
#define MOD 1000000007
using namespace std;
int f[N][N][2][2], F[N];
int C[N][N], fac[N];


int main()
{
    int n, k;
    scanf("%d%d",&n,&k);

    C[0][0] = 1;
    for(int i = 1; i <= n; i++)
    {
        C[i][0] = 1;
        for(int j = 1; j <= i; j++)
            C[i][j] = (C[i-1][j] + C[i-1][j-1]) % MOD;
    }

    fac[0] = 1; for(int i = 1; i <= n; i++) fac[i] = 1ll * fac[i-1] * i % MOD;

    f[1][0][0][0] = 1;
    f[1][1][0][1] = 1;

    for(int i = 1; i < n; i++)
        for(int j = 0; j <= i; j++)
        {
            for(int s1 = 0; s1 <= 1; s1++) for(int s2 = 0; s2 <= 1; s2++)
            {
                if(!s1) (f[i+1][j+1][s2][0] += f[i][j][s1][s2])%=MOD; // put i+1 on i
                if(i != n-1) (f[i+1][j+1][s2][1] += f[i][j][s1][s2])%=MOD; // put i+1 on i+2
                (f[i+1][j][s2][0] += f[i][j][s1][s2])%=MOD;
            }
        }


    for(int j = 0; j <= n; j++)
    {
        F[j] = f[n][j][0][0] + f[n][j][1][0];
        F[j] = 1ll * F[j] * fac[n-j] % MOD;
    }

    for(int i = n; i >= 0; i--)
        for(int j = n; j > i; j--)
            (F[i] -= 1ll * F[j] * C[j][i] % MOD) %= MOD;

    printf("%d\n",(F[k]+MOD)%MOD);

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值