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;
    }
  • 相关阅读:
    linux防火墙iptables
    etc/fstab
    EDT改成CST
    echo
    dd
    chown
    CAT
    Linux grep
    CHECKSUM比较两表字段值差异
    通过GitHub部署项目到Nginx服务器
  • 原文地址:https://www.cnblogs.com/isakovsky/p/14219382.html
Copyright © 2011-2022 走看看