| Solved | 
A | 
B | 
C | 
D | 
E | 
F | 
G | 
H | 
I | 
J | 
K | 
L | 
M | 
| 2/13 | 
- | 
- | 
Ø | 
- | 
- | 
- | 
- | 
- | 
- | 
O | 
- | 
- | 
- | 
题目链接
https://pintia.cn/problem-sets/1459829212832296960/problems/type/7
Problem C. Optimal Strategy
题意:
有 $n$ 件物品,第 $i$ 件的价值为 $a_i$。
A 和 B 轮流取物品,A 先手。
每个人都要最大化自己取到的物品的价值和,求有多少种可能的游戏过程。
思路:
记价值为 $i$ 的物品有 $cnt_i$ 个。
当剩余物品中最大价值为 $x$ 时:
- 当 $cnt_x$ 为偶数时,当一个人取了 $x$ 后,下一个回合另一个人也必须取 $x$,下下回合可以随意取,这样最终每个人都能拿到 $\frac {cnt_x} {2}$ 个 $x$。
 
- 当 $cnt_x$ 为奇数时,在一开始取走一个 $x$,转化为偶数情况。
 
按照物品价值从小到大考虑,记价值 $\le i$ 的物品有 $f_i$ 种游戏过程:
$f_i=f_{i-1}*cnt_i!*\binom{\lfloor\frac{cnt_i}{2}\rfloor+\sum_{j=1}^{i-1}{cnt_j}}{\lfloor\frac{cnt_i}{2}\rfloor}$。
代码:
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 44 45 46 47 48 49 50 51 52 53 54 55
   | #include <bits/stdc++.h> #define SZ(x) (int)(x).size() #define ALL(x) (x).begin(),(x).end() #define PB push_back #define EB emplace_back #define MP make_pair #define FI first #define SE second using namespace std; typedef double DB; typedef long double LD; typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> PII; typedef vector<int> VI; typedef vector<LL> VLL; typedef vector<PII> VPII;
  const int N=1e6+5; const LL MOD=998244353; int cnt[N]; LL fac[N],invfac[N],f[N],sum[N]; LL binom(int n,int m) {     return fac[n]*invfac[m]%MOD*invfac[n-m]%MOD; } LL qpow(LL a,LL b) {     LL ret=1;     while(b) {         if(b&1) ret=ret*a%MOD;         a=a*a%MOD;         b>>=1;     }     return ret; } int main() {     ios::sync_with_stdio(false);     cin.tie(nullptr);     int n;cin>>n;     fac[0]=1;     for(int i=1;i<=n;i++) fac[i]=fac[i-1]*i%MOD;     invfac[n]=qpow(fac[n],MOD-2);     for(int i=n-1;~i;i--) invfac[i]=invfac[i+1]*(i+1)%MOD;     for(int i=1;i<=n;i++) {         int x;cin>>x;         ++cnt[x];     }     for(int i=1;i<=n;i++) sum[i]=sum[i-1]+cnt[i];     f[0]=1;     for(int i=1;i<=n;i++) {         if(cnt[i]) f[i]=f[i-1]*fac[cnt[i]]%MOD*binom(cnt[i]/2+sum[i-1],cnt[i]/2)%MOD;         else f[i]=f[i-1];     }     cout<<f[n]<<'\n';     return 0; }
   | 
 
Problem K. Search For Mafuyu
题意:
树形图,A 在点 $1$,B 可能在除了 $1$ 以外的任何点,概率是一样的。
A 要找到 B,如果 A 采取最优策略,求找到 B 的最小期望时间。
思路:
显然欧拉遍历所需步数是最少的。
代码:
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 44 45 46 47
   | #include <bits/stdc++.h> #define SZ(x) (int)(x).size() #define ALL(x) (x).begin(),(x).end() #define PB push_back #define EB emplace_back #define MP make_pair #define FI first #define SE second using namespace std; typedef double DB; typedef long double LD; typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> PII; typedef vector<int> VI; typedef vector<LL> VLL; typedef vector<PII> VPII;
  const int N=105; VI g[N]; LL sum,step; void dfs(int u,int fa) {     for(auto v:g[u]) if(v!=fa) {         ++step;         sum+=step;         dfs(v,u);         ++step;     } } int main() {     ios::sync_with_stdio(false);     cin.tie(nullptr);     int T;cin>>T;     while(T--) {         int n;cin>>n;         for(int i=1;i<=n;i++) g[i].clear();         step=sum=0;         for(int i=1;i<n;i++) {             int u,v;cin>>u>>v;             g[u].PB(v);             g[v].PB(u);         }         dfs(1,0);         cout<<fixed<<setprecision(10)<<1.0*sum/(n-1)<<'\n';     }     return 0; }
   |