luoguP3750 [六省联考2017]分手是祝愿 概率期望DP + 贪心

本文介绍了一种结合状压动态规划与贪心策略解决特定类型数学问题的方法。通过计算从状态i到i-1的期望步数,利用递推公式解决了复杂问题。对于i大于k的情况给出了具体的转移方程,并说明了i小于等于k时的特殊情况处理方式。此外,还详细解释了如何通过枚举和位运算来确定初始状态的最小步数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

...........真的神状态了,没办法去想的状态...................

考试的时候选择$50$分贪心+$15$分状压吧,别的点就放弃算了........

令$f[i]$表示从最小步数为$i$时走到最小步数为$i - 1$的状态的期望步数

(所以题目中的$k$实际上是个提示...........................)

那么当$i > k$时,有$f[i] = \frac{i}{n} + \frac{n - i}{n} * (1 + f[i] + f[i + 1])$

移项后转移就是递推式了

当$i \leqslant k$时,有$f[i] = f[i + 1] + 1$

 

怎么求解初始状态的最小步数呢?

可以发现,我们一定是从$n$慢慢点到$1$最优

那么,$1$个点会不会被点就跟它的倍数有多少个$1$有关

倒叙枚举$i$,再枚举$i$的倍数看看就好了.....

复杂度$O(n \log n)$

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;

extern inline char gc() {
    static char RR[23456], *S = RR + 23333, *T = RR + 23333;
    if(S == T) fread(RR, 1, 23333, stdin), S = RR;
    return *S ++;
}
inline int read() {
    int p = 0, w = 1; char c = gc();
    while(c > '9' || c < '0') { if(c == '-') w = -1; c = gc(); }
    while(c >= '0' && c <= '9') p = p * 10 + c - '0', c = gc();
    return p * w;
}

#define ri register int
#define sid 200500

const int mod = 100003;
int n, k, nj = 1, mis, ans;
int inv[sid], f[sid], v[sid];

int main() {
    n = read(); k = read();
    for(ri i = 1; i <= n; i ++) v[i] = read();

    for(ri i = n; i >= 1; i --)
    for(ri j = i + i; j <= n; j += i) v[i] ^= v[j];
    for(ri i = 1; i <= n; i ++) mis += v[i];

    inv[1] = 1;
    for(ri i = 2; i <= n; i ++)
    inv[i] = 1ll * (mod - mod / i) * inv[mod % i] % mod;
    for(ri i = 1; i <= n; i ++) nj = 1ll * nj * i % mod;

    for(ri i = n; i > k; i --)
    f[i] = (n + 1ll * (n - i) * f[i + 1] % mod) * inv[i] % mod;
    for(ri i = k; i; i --) f[i] = 1;
    
    for(ri i = 1; i <= mis; i ++) (ans += f[i]) %= mod;
    printf("%d\n", 1ll * ans * nj % mod); 
    return 0;
}

 

转载于:https://www.cnblogs.com/reverymoon/p/9512058.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值