• [六省联考2017]分手是祝愿——期望DP


    原题戳这里
    首先可以确定的是最优策略一定是从大到小开始,遇到亮的就关掉,因此我们可以(O(nlogn))的预处理出初始局面需要的最小操作次数(tot)
    然后容(hen)易(nan)发现即使加上了随机,那(tot)个也一定要被操作,也就是说操作这(tot)个之外的都是没用的。
    于是就可以(dp)了,设(f[i])表示还剩(i)个必须要操作的未操作,转移如下:
    (f[i]=frac{i}{n}+frac{n-i}{n}(f[i]+f[i+1]+1))
    移项得到(f[i]=frac{(n-i)f[i+1]+n}{i})
    边界(f[n]=1)
    最后如果(totleqslant k)直接输出(tot*n!),否则输出(k+n!sumlimits_{i=k+1}^{tot}f[i])

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define MAXN 100000
    #define MOD 100003
    
    int n, k, tot, ans, a[MAXN + 5], f[MAXN + 5], fac = 1;
    vector<int> G[MAXN + 5];
    
    int fpow(int x, int p) {
    	int ret = 1;
    	while(p) {
    		if(p & 1) ret = 1LL * ret * x % MOD;
    		x = 1LL * x * x % MOD;
    		p >>= 1;
    	}
    	return ret;
    }
    
    int main() {
    	scanf("%d%d", &n, &k);
    	for (int i = 1; i <= n; ++i) {
    		scanf("%d", &a[i]);
    		for (int j = i; j <= n; j += i) G[j].push_back(i);
    		fac = 1LL * fac * i % MOD;
    	}
    	for (int i = n; i >= 1; --i) {
    		if(!a[i]) continue;
    		tot++;
    		for (auto j : G[i]) a[j] ^= 1;
    	}
    	if (tot <= k) ans = 1LL * tot * fac % MOD;
    	else {
    		f[n] = 1, ans = k;
    		for (int i = n - 1; i >= 1; --i) f[i] = (1LL * (n - i) * f[i + 1] % MOD + n) * fpow(i, MOD-2) % MOD;
    		for (int i = k + 1; i <= tot; ++i) ans = (ans + f[i]) % MOD;
    		ans = 1LL * ans * fac % MOD;
    	}
    	printf("%d
    ", ans);
    	return 0;
    }
    
  • 相关阅读:
    Java学习笔记——继承、接口、多态
    Java学习笔记,前两章总结
    网络攻防第十一周总结
    第十一周网络攻防作业
    第十周网络作业
    第九周网络攻防作业
    第八周网络攻防作业
    第七周网络攻防作业
    第六周网络攻防作业
    第五周网络攻防作业
  • 原文地址:https://www.cnblogs.com/dummyummy/p/11038169.html
Copyright © 2020-2023  润新知