码迷,mamicode.com
首页 > 其他好文 > 详细

10.25 AHSOFNU 校内模拟

时间:2017-10-27 21:34:06      阅读:156      评论:0      收藏:0      [点我收藏+]

标签:turn   scanf   names   输入   col   inline   std   端点   相同   

//今天泉七考我们的题 感觉大家都很巨大啊~

 

切题(problem)

【问题描述】
  小 Z 和小 G 都是切题好手,他们经常抢着切题,今天他们已经 决定好了 n 道要切的题目并准备按照顺序切掉这些题。每道题都有一个难度值 di,两个人都想自己切掉的题难度值之和最大,但他们又不屑于切对方切过的题,于是两人制定了如下规则:一开始,决定谁切下一道题的权利在作为老大的小 Z 手里,拥有这个权利的人可以指定谁切下一道题,当被指定的那个人切完题后,这个权利会转移到没切这道题的那个人手上(可以是自己)。两人都很强,所以他们总是进行最优的决策以使自己切到的题难度值之和最大。F 大爷想知道他们最后各自切的题的难度值之和。

【输入格式】
  第一行一个正整数 n,表示题数。
  接下来 n 个正整数 di,依次表示第 i 道要切的题的难度值。

【输出格式】
  输出两个用空格隔开的整数,分别表示小 Z 和小 G 切掉的题的难度值之和。

【样例输入】
  4
  2 3 3 3

【样例输出】
  6 5

【数据范围】
  对于 20%的数据,n<=5;
  对于 40%的数据,n<=50;
  对于 60%的数据,n<=500;
  对于 80%的数据,n<=5000;
  对于 100%的数据,n<=50000,di<=100。

Solution:

  由于权利在小 Z 或小 G 手上,而且转移只有取与不取,我们可以考虑DP。

  每个状态向后转移只有两种,我们可以倒着DP,dp[ i ] [0/1]表示还剩下 i 道题,考虑小 Z 之后的收益之和,所以小 Z 会对两者去max,小 G 会对两者取min。

 1 #include<cstdio>
 2 #define MAXN 50005
 3 using namespace std;
 4 int f[2][MAXN],d[MAXN],sum=0;
 5 inline int Max(int a,int b){return a>b?a:b;}
 6 inline int Min(int a,int b){return a<b?a:b;}
 7 int main(){
 8     freopen("problem.in","r",stdin);
 9     freopen("problem.out","w",stdout);
10     int n;scanf("%d",&n);
11     for(int i=1;i<=n;i++) scanf("%d",&d[i]),sum+=d[i];
12     for(int i=n;i>=1;i--) {
13         f[0][i]=Max(f[0][i+1],f[1][i+1]+d[i]);//small Z 
14         f[1][i]=Min(f[0][i+1],f[1][i+1]+d[i]);//small G 
15     } 
16     printf("%d %d",f[0][1],sum-f[0][1]);
17     return 0;
18 } 

 

开车(car)

【问题描述】
  老司机小 Q 要在一个十字路口指挥车队开车,这个十字路口可 以描述为一个 n*n 的矩阵,其中第 2 行到第 n-1 行都各有一道横向车 道,第 2 列到第 n-1 列都各有一条纵向车道。飙车开始前,小 Q 可以 在每条车道的两端(横向车道为从左到右第 1 格和第 n 格,纵向车道 为从上到下的第 1 格和第 n 格)安置一辆大卡车。安置结束后,小 Q可以下令让所有大卡车同时向车道的另一端行驶,所有的卡车速度都相同。小 Q 要合理安排这些卡车,使得它们在行驶过程中不会相撞;另外一些格子上有小 C 放置的巨石,这些格子不能通过卡车。小 Q希望安置的卡车最多,请你求出最多的卡车数。

【输入格式】
  第一行两个非负整数 n 和 m,分别表示十字路口大小和巨石数量。
  接下来 m 行,每行两个正整数 xi,yi,表示在第 xi 行第 yi 列有一个巨石。

【输出格式】
  输出一个整数,表示答案。

【样例输入】
  4 3
  3 1
  3 2
  3 3

【样例输出】
  1

【数据范围】
  对于 20%的数据,n<=5;
  对于 40%的数据,n<=10;
  对于 70%的数据,n<=1000;
  对于 100%的数据,3<=n<=200000,m<=200000。

Solution:

  由于存不存在可能,无论行列都只与 n-i+1 有关,暴力枚举即可。

 1 #include<cstdio>
 2 #include<cstring>
 3 #define MAXN 200005
 4 #define debug 0
 5 using namespace std;
 6 int n,m,ans=0;
 7 bool a[MAXN][2];
 8 int main(){
 9     freopen("car.in","r",stdin);
10     freopen("car.out","w",stdout);
11     scanf("%d%d",&n,&m);
12     memset(a,true,sizeof(a));
13     while(m--){
14         int x,y;scanf("%d%d",&x,&y);
15         a[x][0]=false;a[y][1]=false;
16     }
17     #if debug
18         for(int i=1;i<=n;i++) printf("%d ",a[i][0]);printf("its 0\n");
19         for(int i=1;i<=n;i++) printf("%d ",a[i][1]);printf("its 1\n");
20     #endif
21     for(int i=2;i<=n-1;i++){
22         if(a[i][0]==true) ans++; 
23         if(a[i][1]==true) ans++;
24     }
25     if(n&1) if(a[n/2+1][0]&&a[n/2+1][1]) ans--;
26     printf("%d",ans);
27     return 0;
28 } 

 

学习(study)

【问题描述】
  巨弱小 D 准备学习,有 n 份学习资料给他看,每份学习资料的 内容可以用一个正整数 ai 表示。小 D 如果在一天内学习了多份资料,他只能记住这些资料的内容表示成的整数的最大公约数的部分。学习若干份资料得到的收益是小 D 记下的内容之和,也就是学习的资料 数乘上这些资料内容的最大公约数。小 D 今天准备挑一段连续的资料来学习,请你告诉他最大的收益是多少。

【输入格式】
  第一行一个正整数 n,表示资料数。
  接下来 n 个正整数 ai,分别表示每份资料的内容。

【输出格式】
  输出一个整数,表示答案。

【样例输入】
  5
  30 60 20 20 20

【样例输出】
  80

【数据范围】
  对于 20%的数据,n<=100;
  对于 40%的数据,n<=1000;
  对于 70%的数据,n<=100000;
  对于 100%的数据,n<=500000,ai<=10^9。

 

Solution:

  对于每个右端点,其对应的区间的gcd只有log种(gcd每次变小必然会少一个质因子,而一个数的质因子只有log个),从左向右推的同时维护每种gcd的左端点即可。

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 #define MN 500000
 5 int gcd(int x,int y){return y?gcd(y,x%y):x;}
 6 int a[MN+5],p[MN+5],pn,np[MN+5],npn;
 7 int main()
 8 {
 9     freopen("study.in","r",stdin);
10     freopen("study.out","w",stdout);
11     int n,i,j,x;
12     long long ans=0;
13     scanf("%d",&n);
14     for(i=1;i<=n;++i)
15     {
16         scanf("%d",&a[i]);
17         for(j=1;j<=pn;++j)a[p[j]]=gcd(a[p[j]],a[i]);p[++pn]=i;
18         for(j=1,npn=0;j<=pn;++j)if(j==pn||a[p[j]]!=a[p[j+1]])np[++npn]=p[j];
19         for(j=1,pn=npn;j<=pn;++j)p[j]=np[j],ans=max(ans,1LL*a[p[j]]*(i-p[j-1]));
20     }
21     printf("%lld",ans);
22     fclose(stdin);fclose(stdout);return 0;
23 }

 

10.25 AHSOFNU 校内模拟

标签:turn   scanf   names   输入   col   inline   std   端点   相同   

原文地址:http://www.cnblogs.com/drizzly/p/7739869.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!