Educational Codeforces Round 55 (Rated for Div. 2)

A.Vasya and Book

三种情况讨论一下

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int main()
 4 {
 5     int _;
 6     scanf("%d",&_);
 7     while(_--)
 8     {
 9         int n,d,x,y;
10         scanf("%d%d%d%d",&n,&x,&y,&d);
11         if((n-y)%d!=0&&(x-y)%d!=0&&(y-1)%d!=0)
12         {
13             printf("-1\n");
14         }
15         else
16         {
17             int s=n;
18             if((y-x)%d==0)s=min(s,abs(y-x)/d);
19             if((n-y)%d==0)s=min(s,(n-y)/d+(n+d-1-x)/d);
20             if((y-1)%d==0)s=min(s,(x+d-2)/d+(y-1)/d);
21             printf("%d\n",s);
22         }
23     }
24     return 0;
25 }
View Code

B. Vova and Trophies

把G切开 这样共有k段

针对k的数量分三类处理

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 char a[100001];
 4 int k,l[100001],r[100001];
 5 int main()
 6 {
 7     int n;
 8     scanf("%d\n",&n);
 9     scanf("%s",a);
10     int i=0;
11     while(i<n)
12     {
13         while(i<n&&a[i]!='G')i++;
14         if(i>=n)break;
15         k++;
16         l[k]=i;
17         while(i<n&&a[i]=='G')i++;
18         r[k]=i-1;
19     }
20     int ans=k==0?0:r[1]-l[1]+1+(k>=2);
21     for(i=2;i<=k;i++)
22     {
23         if(l[i]-2==r[i-1])ans=max(ans,r[i]+r[i-1]-l[i]-l[i-1]+3-(k<=2));
24         else ans=max(ans,r[i]-l[i]+1+(k>=2));
25     }
26     printf("%d",ans);
27     return 0;
28 }
View Code

C. Multi-Subject Competition

如果一个项目能派x人出战,且x人的战斗值之和为正

那么就把它加入到最终每个项目派x人出战的贡献中

最后扫一遍答案

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 struct node
 4 {
 5     int c,r;
 6 }nu[100001];
 7 bool cmp(node i,node j)
 8 {
 9     return i.r!=j.r?i.r<j.r:i.c>j.c;
10 }
11 int s[100001];
12 int main()
13 {
14     int n,m;
15     scanf("%d%d",&n,&m);
16     for(int i=1;i<=n;i++)
17     {
18         scanf("%d%d",&nu[i].r,&nu[i].c);
19     }
20     sort(nu+1,nu+n+1,cmp);
21     int N=0,ss;
22     for(int i=1;i<=n;i++)
23     {
24         if(nu[i].r!=nu[i-1].r){ss=0;N=0;}
25         ss+=nu[i].c;
26         N++;
27         if(ss>0)s[N]+=ss;
28     }
29     int ans=0;
30     for(int i=1;i<=n;i++)ans=max(s[i],ans);
31     printf("%d",ans);
32     return 0;
33 }
View Code

D. Maximum Diameter Graph

每个度大于等于2的点在最后的图中一定形成一条链

然后链的头和尾加一个度为1的点(如果有)

构不成图就是度大于等于2的每个点度-2的和小于度为1的点数量-2

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 vector<int> n0,n1,nx;
 4 int main()
 5 {
 6     int n,s1=0,s2=0,n2=0,x;
 7     scanf("%d",&n);
 8     for(int i=1;i<=n;i++)
 9     {
10         scanf("%d",&x);
11         if(x==1)
12         {
13             n0.push_back(i);
14             s1++;
15         }
16         else
17         {
18             n1.push_back(i);
19             nx.push_back(x-2);
20             s2+=x-2;
21             n2++;
22         }
23     }
24     if(s1>s2+2){printf("NO");return 0;}
25     printf("YES %d\n%d\n",n2+(s1>=1)+(s1>=2)-1,s1+n2-1);
26     if(s1>=1)printf("%d %d\n",n1[0],n0[s1-1]),s1--;
27     if(s1>=1)printf("%d %d\n",n1[n2-1],n0[s1-1]),s1--;
28     int i=0;
29     while(s1)
30     {
31         while(nx[i]==0)i++;
32         nx[i]--;
33         printf("%d %d\n",n1[i],n0[s1-1]);
34         s1--;
35     }
36     for(i=0;i<n2-1;i++)
37         printf("%d %d\n",n1[i],n1[i+1]);
38     return 0;
39 }
View Code

E. Increasing Frequency

贪心+最长连续字段和

答案=[l,r]*这一段(众数个数-C个数)+C总的个数

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int nc[500001],s[500001];
 4 int pre[500001];
 5 int main()
 6 {
 7     int n,c,x;
 8     int ans=0;
 9     scanf("%d%d",&n,&c);
10     for(int i=1;i<=n;i++)
11     {
12         scanf("%d",&x);
13         if(x==c)
14             nc[i]=nc[i-1]+1;
15         else
16         {
17             nc[i]=nc[i-1];
18             s[x]=max(1,s[x]+1-nc[i]+nc[pre[x]]);
19             pre[x]=i;
20             ans=max(s[x],ans);
21         }
22     }
23     printf("%d",ans+nc[n]);
24     return 0;
25 }
View Code

F. Speed Dial

字典树+dp

dp[x][k][fa]表示字典树上以x为根的子树上 可以安排k个按钮 且之前的按钮在fa的位置上

dp2[x][k][fa][s]表示字典树上以x为根的子树上 可以安排k个按钮且x不能被安排为按钮 且之前的按钮在fa的位置上 考虑前s个儿子的子树上可以安排按钮

那么转移就很显然了

dp[x][k][fa]=min(dp[x][k-1][x],dp2[x][k][fa][儿子的数量]+x和fa的距离*当前节点拨号次数)

dp2[x][k][fa][s]=min(dp[第s个儿子][j][fa]+dp2[x][k-j][fa][s-1])(0<=j<=k)

所以记忆化搜索搞一下就好了

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=507,K=11,inf=1e9;
 4 struct node
 5 {
 6     int nxt[10];
 7     int cnt;
 8     node()
 9     {
10         memset(nxt,-1,sizeof(nxt));
11         cnt=0;
12     }
13 }trie[N];
14 int cnt;
15 int h[N];
16 int n,k;
17 int dp[N][K][N];
18 int dp2[N][K][N][K];
19 void add(string s,int m)
20 {
21     int cur=0;
22     for(int i=0;i<s.size();i++)
23     {
24         int x=s[i]-'0';
25         if(trie[cur].nxt[x]==-1)
26         {
27             trie[cnt]=node();
28             trie[cur].nxt[x]=cnt;
29             h[cnt]=h[cur]+1;
30             cnt++;
31         }
32         cur=trie[cur].nxt[x];
33     }
34     trie[cur].cnt+=m;
35 }
36 int work(int x,int k,int fa)
37 {
38     if(dp[x][k][fa]!=-1)return dp[x][k][fa];
39     vector<int> son;
40     for(int i=0;i<=9;i++)
41         if(trie[x].nxt[i]!=-1)
42             son.push_back(trie[x].nxt[i]);
43     dp[x][k][fa]=inf;
44     if(k>0)
45         dp[x][k][fa]=work(x,k-1,x);
46     dp2[x][k][fa][0]=0;
47     for(int i=1;i<=son.size();i++)
48     {
49         dp2[x][k][fa][i]=inf;
50         for(int j=0;j<=k;j++)
51             dp2[x][k][fa][i]=min(dp2[x][k][fa][i],work(son[i-1],j,fa)+dp2[x][k-j][fa][i-1]);
52     }
53     dp[x][k][fa]=min(dp[x][k][fa],dp2[x][k][fa][son.size()]+(h[x]-h[fa])*trie[x].cnt);
54     return dp[x][k][fa];
55 }
56 int main()
57 {
58     trie[0]=node();
59     cnt=1;
60     cin>>n>>k;
61     for(int i=1;i<=n;i++)
62     {
63         string s;int m;
64         cin>>s>>m;
65         add(s,m);
66     }
67     memset(dp,-1,sizeof(dp));
68     printf("%d",work(0,k,0));
69     return 0;
70 }
View Code

G. Petya and Graph

最大权闭合子图

把每条边都当做一个点 并与其两个顶点连一条容量无穷大的边 与s连一条容量为权值的边

把每个顶点连一条与t容量为权值的边

求s到t的最大流 用边权值的和减去最大流就是答案

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int MXE=6000000,MX=1000050;
  4 const long long inf=1e15;
  5 struct MaxFlow
  6 {
  7     struct Edge
  8     {
  9         int v,nxt;
 10         long long w;
 11     }edge[MXE];
 12     int tot,num,s,t;
 13     int head[MX];
 14     void init()
 15     {
 16         memset(head,-1,sizeof(head));
 17         tot=0;
 18     }
 19     void add(int u,int v,long long w)
 20     {
 21         edge[tot].v=v;
 22         edge[tot].w=w;
 23         edge[tot].nxt=head[u];
 24         head[u]=tot++;
 25         edge[tot].v=u;
 26         edge[tot].w=0;
 27         edge[tot].nxt=head[v];
 28         head[v]=tot++;
 29     }
 30     int d[MX],vis[MX],gap[MX];
 31     void bfs()
 32     {
 33         memset(d, 0, sizeof(d));
 34         memset(gap, 0, sizeof(gap));
 35         memset(vis, 0, sizeof(vis));
 36         queue<int>q;
 37         q.push(t);
 38         vis[t] = 1;
 39         while (!q.empty())
 40         {
 41             int u=q.front();
 42             q.pop();
 43             for (int i=head[u];~i;i=edge[i].nxt) {
 44                 int v = edge[i].v;
 45                 if (!vis[v]) {
 46                     d[v]=d[u]+1;
 47                     gap[d[v]]++;
 48                     q.push(v);
 49                     vis[v]=1;
 50                 }
 51             }
 52         }
 53     }
 54 
 55     int last[MX];
 56     long long dfs(int u,long long f)
 57     {
 58         if (u==t) return f;
 59         long long sap=0;
 60         for (int i=last[u];~i;i=edge[i].nxt)
 61         {
 62             int v=edge[i].v;
 63             if (edge[i].w>0&&d[u]==d[v]+1)
 64             {
 65                 last[u]=i;
 66                 int tmp=dfs(v, min(f-sap, edge[i].w));
 67                 edge[i].w-=tmp;
 68                 edge[i^1].w+=tmp;
 69                 sap+=tmp;
 70                 if(sap==f)return sap;
 71             }
 72         }
 73         if (d[s]>=num) return sap;
 74         if (!(--gap[d[u]])) d[s]=num;
 75         ++gap[++d[u]];
 76         last[u]=head[u];
 77         return sap;
 78     }
 79 
 80     long long solve(int st,int ed,int n)
 81     {
 82         long long flow=0;
 83         num=n;
 84         s=st;
 85         t=ed;
 86         bfs();
 87         memcpy(last, head, sizeof(head));
 88         while (d[s]<num)flow+=dfs(s,inf);
 89         return flow;
 90     }
 91 }F;
 92 int m,n;
 93 int main()
 94 {
 95     scanf("%d%d",&n,&m);
 96     int i,x,u,v;
 97     F.init();
 98     long long ans=0;
 99     for(i=1;i<=n;i++)
100     {
101         scanf("%d",&x);
102         F.add(i,n+m+1,x);
103     }
104     for(i=1;i<=m;i++)
105     {
106         scanf("%d%d%d",&u,&v,&x);
107         F.add(n+i,u,inf);
108         F.add(n+i,v,inf);
109         F.add(0,n+i,x);
110         ans+=x;
111     }
112     printf("%lld",ans-F.solve(0,n+m+1,n+m+2));
113     return 0;
114 }
View Code
posted @ 2018-11-29 21:12  hermit-lei  阅读(151)  评论(0)    收藏  举报