Codeforces Round #259 (Div. 1)
A题:最大值为i的期望为(in−(i−1)n)∗i/mn,那么总期望为∑m1(in−(i−1)n)∗i/mn,然后化简一下公式,答案为m−∑m−11i/mn
B题:状压DP,只需要用到小于59的素数,一共有16个,dp[n][s]表示当前放到第n个数字,素数使用的集合为s的最小值,S[k]表示k数字对应会用掉哪几个素数,然后进行状态转移
dp(n, s) = dp(n - 1, s^S[k]) + abs(k - num[n])
C题:dfs构造,题目中其实给了提示,最多不超过4n步,那么其实如果给定的是一棵树,在这个步骤内是绝对有办法构造出来的,可以选一个根结点出来,然后当成一棵树,对于一条路径,如果走两遍,其实就等于没走,那么对于每条路径,只需要走一遍走到底,再走回根结点,如果当前一个位置不满足,就退一步在进一步,然后注意根结点,其实根结点是无法回退的,但是其实根结点如果不满足,那么我只要让最后回到根结点的一步不走就可以了,这样搜完,在判断一下还有没结点不满足,如果有,肯定是多棵树构造不出来的情况
代码:
A:
#include <cstdio>
#include <cstring>
#include <cmath>
int m, n;
int main() {
scanf("%d%d", &m, &n);
double ans = 0;
for (int i = 1; i < m; i++)
ans += pow((m - i) * 1.0 / m, n);
printf("%.12lf\n", m * 1.0 - ans);
return 0;
}
B:
#include <cstdio>
#include <cstring>
#include <cstdlib>
const int N = 105;
const int MAXN = (1<<16) + 5;
const int INF = 0x3f3f3f3f;
int n, num[N], prime[N], pn = 0, vis[N], to[N];
void get_prime() {
for (int i = 2; i < 59; i++) {
if (vis[i]) continue;
prime[pn++] = i;
for (int j = i * i; j < 60; j += i) {
vis[j] = 1;
}
}
}
int tra(int num) {
int ans = 0;
for (int i = 0; i < pn; i++) {
if (num % prime[i] == 0) ans |= (1<<i);
while (num % prime[i] == 0) num /= prime[i];
}
return ans;
}
int dp[N][MAXN], zh[N][MAXN][2];
void print(int now, int s) {
if (now == 0) return;
print(now - 1, zh[now][s][0]);
printf("%d%c", zh[now][s][1], now == n? '\n' : ' ');
}
int main() {
get_prime();
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d", &num[i]);
for (int i = 1; i < 59; i++)
to[i] = tra(i);
int maxs = (1<<pn);
memset(dp, INF, sizeof(dp));
memset(dp[0], 0, sizeof(dp[0]));
for (int i = 1; i <= n; i++) {
for (int j = 0; j < maxs; j++) {
for (int k = 1; k < 60; k++) {
if ((j&to[k]) != to[k]) continue;
int tmp = dp[i - 1][j^to[k]] + abs(k - num[i]);
if (dp[i][j] > tmp) {
dp[i][j] = tmp;
zh[i][j][0] = (j^to[k]);
zh[i][j][1] = k;
}
}
}
}
int Min = INF, Min_v;
for (int i = 0; i < maxs; i++) {
if (dp[n][i] < Min) {
dp[n][i] = Min;
Min_v = i;
}
}
print(n, Min_v);
return 0;
}
C:
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
const int N = 100005;
int n, m, x[N], now[N], vis[N], nv;
vector<int> g[N], ans;
void dfs(int u, int p) {
vis[u] = 1;
ans.push_back(u);
now[u] ^= 1;
for (int i = 0; i < g[u].size(); i++) {
int v = g[u][i];
if (vis[v]) continue;
dfs(v, u);
}
if (x[u]^now[u]) {
if (p != 0) {
ans.push_back(p);
ans.push_back(u);
now[p] ^= 1;
now[u] ^= 1;
}
}
if (p != 0) {
ans.push_back(p);
now[p] ^= 1;
}
}
bool judge() {
if (x[nv]^now[nv]) {
if (ans.size() == 0) return false;
now[nv] ^= 1;
ans.pop_back();
}
for (int i = 1; i <= n; i++)
if (x[i]^now[i]) return false;
return true;
}
int main() {
scanf("%d%d", &n, &m);
int u, v;
while (m--) {
scanf("%d%d", &u, &v);
g[u].push_back(v);
g[v].push_back(u);
}
for (int i = 1; i <= n; i++)
scanf("%d", &x[i]);
memset(now, 0, sizeof(now));
for (int i = 1; i <= n; i++) {
if (x[i]^now[i]) {
nv = i;
dfs(i, 0);
break;
}
}
if (judge()) {
int tmp = ans.size();
printf("%d\n", tmp);
for (int i = 0; i < tmp; i++) {
printf("%d%c", ans[i], i == ans.size() - 1 ? '\n' : ' ');
}
}
else printf("-1\n");
return 0;
}