zoukankan      html  css  js  c++  java
  • [六省联考2017]分手是祝愿(期望+DP)

    题解

    很容易想出来最优策略是什么。

    就是从n到1看到开着的灯就把它关了

    我们预处理出当前状态把灯全部关闭后的最少步数cnt

    然后我们的主人公就要瞎按。。。

    设dp[i]代表当前状态最优解为i步时走到dp[i-1]用过步数的期望。

    现在我们考虑如何转移到dp[i]

    当我们这一步走到当前最优策略的一步时。

    dp[i]=i/n*1

    当我们这一步没有走到当前最优策略的一步时。

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

    所以 dp[i]=i/n+(n-i)/n*(dp[i+1]+1+dp[i])

    化简一下 dp[i]=(n+(n-i)*dp[i+1])/i;

    这样求出dp后答案就是dp[1]+dp[2]+...+dp[cnt]

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<cmath>
     5 #include<algorithm>
     6 #include<vector>
     7 using namespace std;
     8 const long long N=1000100;
     9 const long long mod=100003;
    10 vector<long long>vec[N];
    11 long long n,k,inv[N],a[N],cnt,dp[N],ans;
    12 long long read(){
    13     long long sum=0,f=1;
    14     char ch=getchar();
    15     while(ch<'0'||ch>'9'){
    16         if(f=='-')f=-1;
    17         ch=getchar();
    18     }
    19     while(ch<='9'&&ch>='0'){
    20         sum=(sum<<1)+(sum<<3)+ch-'0';
    21         ch=getchar();
    22     }
    23     return sum;
    24 }
    25 int main(){
    26     n=read();k=read();
    27 //    scanf("%d%d",&n,&k); 
    28     inv[1]=1;
    29     for(long long i=2;i<=n;i++){
    30         inv[i]=-(mod/i)*inv[mod%i];
    31         inv[i]=(inv[i]%mod+mod)%mod;
    32     }
    33     for(long long i=1;i<=n;i++)
    34         for(long long j=i;j<=n;j+=i){
    35             vec[j].push_back(i);
    36         }
    37     for(long long i=1;i<=n;i++){
    38     //    scanf("%d",&a[i]);
    39         a[i]=read();
    40     }
    41     for(long long i=n;i>=1;i--){
    42         if(a[i]){
    43             for(long long j=0;j<=vec[i].size()-1;j++){
    44                 a[vec[i][j]]^=1;
    45             }
    46             cnt++;
    47         }
    48     }
    49     dp[n]=1;
    50     for(long long i=n-1;i>k;i--){
    51         dp[i]=(n+(n-i)*dp[i+1])%mod*inv[i]%mod;
    52     }
    53     for(long long i=k;i>=1;i--)dp[i]=1;
    54     for(long long i=1;i<=cnt;i++){
    55         ans+=dp[i];
    56         ans%=mod;
    57     }
    58     for(long long i=1;i<=n;i++){
    59         ans*=i;
    60         ans%=mod;
    61     }
    62     printf("%lld",ans);
    63     return 0;
    64 } 
  • 相关阅读:
    HDU 1261 字串数(排列组合)
    Codeforces 488C Fight the Monster
    HDU 1237 简单计算器
    POJ 2240 Arbitrage
    POJ 3660 Cow Contest
    POJ 1052 MPI Maelstrom
    POJ 3259 Wormholes
    POJ 3268 Silver Cow Party
    Codesforces 485D Maximum Value
    POJ 2253 Frogger(最短路)
  • 原文地址:https://www.cnblogs.com/Xu-daxia/p/9614202.html
Copyright © 2011-2022 走看看