bzoj 4872: [Shoi2017]分手是祝愿

题解:

先考虑正常的游戏最优策略:
容易发现,一盏灯能影响的只能是前面的灯,所以最后一盏灯是一定要按的,所以唯一最优策略从后往前找,当遇到亮的灯就按一次。
然后就上期望dp。
fi 表示从最优i步的情况到i-1步的期望操作次数。
对于i<=k显然 fi=1
对于i>k因为是随便按的,所以有 fi=in+(1in)(1+fi+fi+1)
化简后得: fi=n+(ni)fi+1i
然后答案就加一下。
感觉不是很难啊,为什么一点都想不到呢
code:

#include
#include
#include
#include
#define LL long long
using namespace std;
const LL mod=100003;
LL inv[100005],n,k,a[100005],f[100005];
void pre()
{
    inv[1]=1;
    for(LL i=2;i<=n;i++)
        inv[i]=(mod-mod/i)*inv[mod%i]%mod;
}
int main()
{
    scanf("%lld %lld",&n,&k);
    for(LL i=1;i<=n;i++) scanf("%lld",&a[i]);
    pre();
    LL sum=0,fac=1;
    for(LL i=n;i>=1;i--)
    {
        for(LL j=i+i;j<=n;j+=i)
            a[i]^=a[j];
        sum+=a[i];
        (fac*=i)%=mod;
    }
    for(LL i=1;i<=k;i++) f[i]=1;
    for(LL i=n;i>k;i--) f[i]=(n+(n-i)*(f[i+1]))%mod*inv[i]%mod;
    LL ans=0;
    for(LL i=1;i<=sum;i++) (ans+=f[i])%=mod;
    printf("%lld",ans*fac%mod);
}

你可能感兴趣的:(dp,期望dp)