• [六省联考2017]分手是祝愿


    P3750 [六省联考2017]分手是祝愿

    感觉无从下手的概率题。

    想清楚本质并不难。

    瞎按不好考虑。反正有一般的是要直接做的。就考虑最优情况怎么按。

    一个灯最多按一次。所以,最优策略次数一定小于等于n

    从大到小依次按灭即可。把约数改变状态。

    约数处理,枚举i从1~n,枚举倍数加入vector O(nlogn)

    (听说可以拿到80pts了。。)

    随机的部分怎么办?
    发现,最优的策略一定要按特定的几次。并且这些次数按的先后顺序其实没有关系。

    最优情况需要按的次数从多到少,所以,这就有了topo的性质!

    而且,一旦最优策略的剩下的步数确定,答案的期望步数就确定了。与具体局面无关(并不关系到底最优策略怎么操作)!!

    事情就比较好办了。

    假如设f[i]表示,最优策略还要进行i次操作时,到终点的次数。

    然而转移成环,而且没有办法破环(转化成kx+b的线性式可以,但是递推项在分母位置,没有办法取模)

    所以,就一步一步来,设f[i]表示,最优策略还要进行i次操作时,变成操作i-1次期望次数。

    f[i]=i/n*1+(n-i)/n*(f[i]+f[i+1]+1)

    因为,没有先后顺序,所以i个中直接选择哪一个都可以。转移没有问题。

    移项之后,即可倒序递推求解。

    f[n]=1 假如剩下n步的话,那必然每个都要按一次就是最优解,所以,无论怎么按,都能到下一层。

    最后,选取need~k这一段的f值。再加上k,再处理阶乘。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=100000+5;
    const int mod=100003;
    int n,k;
    vector<int>mem[N];
    int inv[N];
    ll f[N];
    int a[N];
    int main(){
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        for(int i=1;i<=n;i++)
            for(int j=i;j<=n;j+=i)
                mem[j].push_back(i);
        inv[1]=1;
        for(int i=2;i<=n;i++) inv[i]=(ll)(mod-mod/i)*inv[mod%i]%mod;
        int nd=0;
        for(int i=n;i>=1;i--){
            if(a[i]){
                for(int j=0;j<(int)mem[i].size();j++){
                    
                    a[mem[i][j]]^=1;
                }
                nd++;
            }
        }
        ll ans=0;
        //cout<<nd<<endl;
        if(nd<=k){
            ans=nd;
        }
        else{
            f[n]=1;
            for(int i=n-1;i>=1;i--) f[i]=((ll)n+(ll)(n-i)*f[i+1]%mod)%mod*inv[i]%mod;
            for(int i=nd;i>k;i--) ans=(ans+f[i])%mod;
            ans=(ans+k)%mod;
        }
        for(int i=1;i<=n;i++) ans=(ans*i)%mod;
        printf("%lld",ans);
        return 0;
    }

    总结:
    1.发现最优策略,发现操作次数一定,答案就一定。所以可以就着最优操作次数下手。(亮灯的数量显然不行。因为变化太大。)这样设计也满足选中就进入下一层,也可能原地不动或者返回上一层。

    2.状态设计不一定要直接指向终点,如果后继比较显然的话,可以尝试这样设计状态。

  • 相关阅读:
    sql小练习
    登录测试点
    游戏签到
    移动端和pc端微信加入群聊
    小说
    微信语言输入
    linux tar压缩解压缩命令详解
    linux使用nginx配置web服务器
    FFmpeg 视频处理入门教程
    Git学习
  • 原文地址:https://www.cnblogs.com/Miracevin/p/9843836.html
Copyright © 2020-2023  润新知