zoukankan      html  css  js  c++  java
  • 10.25 AHSOFNU 校内模拟

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

    切题(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
    ");
    19         for(int i=1;i<=n;i++) printf("%d ",a[i][1]);printf("its 1
    ");
    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 }
  • 相关阅读:
    jQuery中jsonp的跨域处理,no access-control-allow-origin,unexpected token
    doT中嵌套for循环的使用
    c++ new带括号和不带括号
    python装饰器之使用情景分析
    Python中classmethod与staticmethod区别
    python作用域 scope
    duck type鸭子类型
    EAFP和LBYL 两种防御性编程风格
    c++重载、覆盖和隐藏
    c++ 名字粉碎(name mangling)
  • 原文地址:https://www.cnblogs.com/drizzly/p/7739869.html
Copyright © 2011-2022 走看看