zoukankan      html  css  js  c++  java
  • Codeforces Round #683 (Div. 2, by Meet IT)

    A - Add Candies

    题面:题面有点绕,总结一下就是有n个长度的数组,数组值跟下标值一样,a[i]=i;然后问你第i次操作,选一个数组中的值,除了它其他都加i,使得数组值相同,问随机一种情况

    思路:操作n次,输出1,2,3,4,5 … n即可

    B - Numbers Box

    题面:给一个n,m的矩阵,有正负,有操作选两个相邻的值,同乘-1,求这个矩阵最大的之和

    思路:比赛的时候卡了,因为没想清楚,选了个最小的负数,其实,正解是如果出现奇数个负数,选择最小的abs值,偶数个负数就肯定能全部变正

    比赛的时候队友飞快过三题,然后我还在卡B,如果不是队友提醒,可能卡死了

    C - Knapsack

    题面:给两个数n,w,给n长度数组,求数组里选几个有没有w/2~w范围的值

    思路:第一想法背包,但数据n 2e5,w 1e18,好,肯定不行,换一个,排序然后尺取?,于是写了一下,就过了

    #include<bits/stdc++.h>
    #define mem(a,b) memset(a,b,sizeof(a))
    #define ll long long
    #define lson(x) x<<1
    #define rson(x) x<<1|1
    #define mod 998244353
    using namespace std;
    ll ksm(ll a,ll b){
        ll ans=1;
        while(b){
            if(b&1){
                ans*=a;ans%=mod;
            }
            a*=a;a%mod;
            b>>=1;
        }
    }
    const int N=2e5+10;
    int n,m,t;
    ll w;
    ll dp[N];
    struct node{
        int w,num;
        friend bool operator<(const node a,const node b){
            return a.w<b.w;
        }
    }we[N];
    int main(){
        scanf("%d",&t);
        while(t--){
            scanf("%d%lld",&n,&w);
            int f=1,pos;
            for(int i=0;i<n;i++){
                scanf("%lld",&we[i].w);we[i].num=i+1;
                if(we[i].w*2>=w && we[i].w<=w){
                    f=0;pos=i;
                }
            }
            if(!f){
                printf("1
    ");
                printf("%d
    ",we[pos].num);
                continue;
            }
            sort(we,we+n);
            dp[0]=we[0].w;
            for(int i=1;i<n;i++){
                dp[i]=dp[i-1]+we[i].w;
            }
    
            for(int i=0;i<n;i++){
                if(dp[i]*2>=w && dp[i]<=w){
                    f=0;pos=i;break;
                }
                 if(dp[i]*2>=w && dp[i]>w){
                    f=2;pos=i;break;
                }
            }
            int pos2=0;
            if(f==2){
                for(int i=0;i<pos;i++){
                    while((dp[pos]-dp[i])*2<w){pos++;if(pos>n){break;}}
                    if((dp[pos]-dp[i])*2>=w &&(dp[pos]-dp[i])<=w){f=0,pos2=i;break;}
                }
            }
            if(!f){
                printf("%d
    ",pos-pos2+1);
                for(int i=pos2;i<=pos;i++){
                    printf(i==pos?"%d
    ":"%d ",we[i].num);
                }
            }
            else{
                printf("-1
    ");
            }
        }
        return 0;
    }
    
    

    D - Catching Cheaters

    题面:给n,m两个小于5000的数字,然后输入两个长度为n,m 的字符串s1,s2,取两个子串s1’,s2’长度分别是x,y,求4 * lcs(s1’,s2’)-x-y的最大值

    思路:枚举二分贪心wa,因为没考虑n长度字符串的选子串的字母,是个假算法。所以这道题正解就是dp,每次dp题,贪心贪出事。

    那么方法就是,每次找到相同的字符,就会对前一个状态+2,如果没有相同,就会有两种选择,移动s1一位,or移动s2一位,每移动一位值就会-1

    这样我们就可以列出状态转移方程

    s1[i]==s2[j] 的情况比较 dp[i-1][j-1]+2 dp[i-1][j]-1(大于等于0) dp[i][j-1]-1(大于等于0) 哪个大

    s1[i]!=s2[j] 的情况比较 dp[i-1][j]-1(大于等于0) dp[i][j-1]-1(大于等于0) 哪个大

    然后找dp[i][j]的最大值即可

    代码:

    #include<bits/stdc++.h>
    #define mem(a,b) memset(a,b,sizeof(a))
    #define ll long long
    #define lson(x) x<<1
    #define rson(x) x<<1|1
    #define mod 998244353
    using namespace std;
    ll ksm(ll a,ll b){
        ll ans=1;
        while(b){
            if(b&1){
                ans*=a;ans%=mod;
            }
            a*=a;a%mod;
            b>>=1;
        }
    }
    const int N=5e3+10;
    int n,m,t;
    char s[N],ss[N];
    int dp[N][N];
    int main(){
        scanf("%d%d",&n,&m);
        scanf("%s",s);
        scanf("%s",ss);
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                if(s[i]==ss[j]){
                    dp[i+1][j+1]=max(dp[i][j]+2,max(max(dp[i+1][j]-1,0),max(dp[i][j+1]-1,0)));
                }
                else{
                    dp[i+1][j+1]=max(max(dp[i+1][j]-1,0),max(dp[i][j+1]-1,0));
                }
            }
        }
        int ans=0;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
               ans=max(dp[i][j],ans);//cout<<dp[i][j]<<" ";
            }
            //cout<<endl;
        }
        printf("%d
    ",ans);
        return 0;
    }
    
    
    
  • 相关阅读:
    Google I/O 官方应用中的动效设计
    浪院长 | spark streaming的使用心得
    Kubernetes 1.12公布:Kubelet TLS Bootstrap与Azure虚拟机规模集(VMSS)迎来通用版本号
    安卓自己定义View进阶-Path基本操作
    2014编程之美初赛第二场
    2015年,即将结束
    查看JVM运行时参数
    使用ThreadPoolExecutor线程池实现并发操作并返回结果
    mysql数据库将查询的多条结果的某些字段合并为一个字段处理
    mysql数据库使用mybatis新增操作返回自增主键的值
  • 原文地址:https://www.cnblogs.com/luoyugongxi/p/13986160.html
Copyright © 2011-2022 走看看