Codeforces 538E Demiurges Play Again(博弈DP)
http://codeforces.com/problemset/problem/538/E
题目大意:
给出一棵树,叶子节点上都有一个值,从1-m。有两个人交替从根选择道路,先手希望到达的叶子节点尽量大,后手希望到达的叶子节点尽量小,叶子节点的放置方案任意。两个人都足够聪明,能够得到的最大值和最小值分别是多少。
思路:
先考虑最大的情况
考虑dp[i]代表i这个节点能达到的最大的数字在这个子树中排第几。
如果当前是先手操作,那么他肯定会往最大的那个子树的方向走,即dp[u]=min(dp[v])
如果当前是后手操作,那么他肯定往最小的走,即dp[u]=Σdp[v],这样就走到了最差子树的最大数字去了。
然后最小的情况类似
1 #include<cstdio> 2 #include<cmath> 3 #include<algorithm> 4 #include<cstring> 5 #include<iostream> 6 int tot,go[400005],next[400005],first[200005]; 7 int n,f1[400005],f2[400005],pd[400005],son[400005],deep[400005]; 8 int read(){ 9 int t=0,f=1;char ch=getchar(); 10 while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();} 11 while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();} 12 return t*f; 13 } 14 void insert(int x,int y){ 15 tot++; 16 go[tot]=y; 17 next[tot]=first[x]; 18 first[x]=tot; 19 } 20 void add(int x,int y){ 21 insert(x,y); 22 insert(y,x); 23 } 24 void dfs(int x,int fa){ 25 int pdd=0; 26 for (int i=first[x];i;i=next[i]){ 27 int pur=go[i]; 28 if (pur==fa) continue; 29 pdd=1; 30 deep[pur]=deep[x]+1; 31 dfs(pur,x); 32 son[x]+=son[pur]; 33 } 34 if (!pdd) son[x]=1,pd[x]=1; 35 } 36 void dfs1(int x,int fa){ 37 if (pd[x]==1) { 38 f1[x]=1; 39 return; 40 } 41 if (deep[x]%2){ 42 f1[x]=0x7fffffff; 43 for (int i=first[x];i;i=next[i]){ 44 int pur=go[i]; 45 if (pur==fa) continue; 46 dfs1(pur,x); 47 f1[x]=std::min(f1[x],f1[pur]); 48 } 49 }else{ 50 f1[x]=0; 51 for (int i=first[x];i;i=next[i]){ 52 int pur=go[i]; 53 if (pur==fa) continue; 54 dfs1(pur,x); 55 f1[x]+=f1[pur]; 56 } 57 } 58 } 59 void dfs2(int x,int fa){ 60 if (pd[x]==1) { 61 f2[x]=1; 62 return; 63 } 64 if (deep[x]%2){ 65 f2[x]=0; 66 for (int i=first[x];i;i=next[i]){ 67 int pur=go[i]; 68 if (pur==fa) continue; 69 dfs2(pur,x); 70 f2[x]+=f2[pur]; 71 } 72 }else{ 73 f2[x]=0x7fffffff; 74 for (int i=first[x];i;i=next[i]){ 75 int pur=go[i]; 76 if (pur==fa) continue; 77 dfs2(pur,x); 78 f2[x]=std::min(f2[x],f2[pur]); 79 } 80 } 81 } 82 int main(){ 83 n=read(); 84 for (int i=1;i<n;i++){ 85 int x=read(),y=read(); 86 add(x,y); 87 } 88 deep[1]=1; 89 dfs(1,0); 90 dfs1(1,0); 91 printf("%d ",son[1]-f1[1]+1); 92 dfs2(1,0); 93 printf("%d\n",f2[1]); 94 return 0; 95 }