zoukankan      html  css  js  c++  java
  • 牛客2020跨年场 B-牛牛想起飞 dp

    传送门

    中文题面就直接复制了

    给定一个长度为 n 的序列a和一个长度为 n 的序列b,对于序列a中的每一个数字$a_i$,牛牛都可以进行以下操作:
    (1) 将数字 $a_i从 a_i$ 变成 $a_i + b_i$ ;
    (2) 将数字 $a_i从 a_i$ 变成 $a_i - b_i$ 。
    牛牛很懒,所以每个数字只能最多进行一次操作,甚至不操作。现在给出一个数字 y ,牛牛想要知道在做合理的操作后能得到模 y 意义下的最大序列和是多少。
    换句话说,设 $a_1' ,a_2', a_3'dots a_n'$是最终得到的 数组的样子,你要使得 $(a_1' + a_2' + a_3'dots +a_n') mod y$结果最大化。
    做出这道题他就能起飞,你能帮帮他吗?

    题解:
    注意数据范围,b和y只有100,因此可以dp出来[0,y-1]这个区间内哪个点能到达,然后找到最大的

    #include<iostream>
    #include<map>
    using namespace std;
    bool mapp[100005];
    int a[100005],b[100005];
    //map<int,bool> getpos;
    int getpos[105];
    int main(){
        int n,y;
        scanf("%d%d",&n,&y);
        int sum=0;
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            sum=(sum+a[i])%y;
        }
        getpos[sum]=1;
        for(int i=1;i<=n;i++){
            scanf("%d",&b[i]);
            for(int j=0;j<y;j++){
                if(getpos[j]==1){
                    if(getpos[(j+b[i])%y]==0)getpos[(j+b[i])%y]=2;
                    if(getpos[(j-b[i]+y)%y]==0)getpos[(j-b[i]+y)%y]=2;
                }
            }
            for(int j=0;j<y;j++){
                if(getpos[j]==2)getpos[j]=1;
            }
        }
        int maxx=0;
        for(int i=0;i<y;i++){
            if(getpos[i]==1)maxx=max(maxx,i);
        }
        printf("%d
    ",maxx);
        
        return 0;
    }
  • 相关阅读:
    项目工程化之git提交规范以及 CHANGELOG生成
    移动端 弹窗-内容可滚动,背景不动
    项目readme文件目录生成工具 treer
    css animation动画
    【网络】从套接字到Web服务器
    【网络】图解HTTP-1
    【MySQL】搞懂ACID原则和事务隔离级别
    【MySQL】备份与恢复
    【MySQL】索引
    【Redis】主从复制原理
  • 原文地址:https://www.cnblogs.com/isakovsky/p/14219382.html
Copyright © 2011-2022 走看看