题面在这里
考虑最优策略是什么
从大到小,遇到亮的灯就按一下,感觉一下应该是最优的
那么问题就变成了有\(t\) 个按钮需要按奇数次
\(f_i\) 表示还有\(i\) 个按钮需要按奇数次,则有: \[
f_i=\frac i n f_{i-1}+\frac {n-i} n f_{i+1} +1
\] 然而这并不太好搞,再转化一下:
\(g_i\) 表示\(i\) 个按钮到\(i-1\) 个按钮需要的期望步数 \[
g_i=\frac i n + \frac {n-i} n (1+g_i+g_{i+1}) \\
g_i=\frac {(n-i)g_{i+1}+n} i
\] \(g_n=1\) ,答案就是\(k+\sum_{i=k+1}^t g_i\)
示例程序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 #include <cstdio> #include <cmath> typedef long long ll;const int maxn=100005 ,MOD=100003 ;int n,m,K,d[maxn];ll f[maxn]; ll power (int a,int b) { ll res=1 ,w=a; while (b){ if (b&1 ) (res*=w)%=MOD; (w*=w)%=MOD; b>>=1 ; } return res; } int main () { scanf ("%d%d" ,&n,&K); for (int i=1 ;i<=n;i++) scanf ("%d" ,&d[i]); for (int i=n;i>=1 ;i--) if (d[i]){ int tj=sqrt (i);d[i]=0 ;m++; for (int j=1 ;j<=tj;j++) if (i%j==0 ){ d[j]^=1 ; if (j*j!=i) d[i/j]^=1 ; } } if (m<=K){ ll ans=m; for (int i=1 ;i<=n;i++) (ans*=i)%=MOD; printf ("%lld" ,ans); return 0 ; } ll ans=K; f[n]=1 ; for (int i=n-1 ;i>K;i--) f[i]=((n-i)*f[i+1 ]+n)%MOD*power(i,MOD-2 )%MOD; for (int i=m;i>K;i--) (ans+=f[i])%=MOD; for (int i=1 ;i<=n;i++) (ans*=i)%=MOD; printf ("%lld" ,ans); return 0 ; }