zoukankan      html  css  js  c++  java
  • [Codeforces #210] Tutorial

    Link:

    Codeforces #210 传送门

    A:

    贪心,对每个值都取最大值,不会有其他解使答案变优

    #include <bits/stdc++.h>
    
    using namespace std;
    #define X first
    #define Y second
    typedef long long ll;
    typedef pair<int,int> P;
    typedef double db;
    const int MAXN=5005,INF=1<<30;
    struct data{int op,l,r,x;}dat[MAXN];
    int n,m,mx[MAXN],vis[MAXN];
    
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
            scanf("%d%d%d%d",&dat[i].op,&dat[i].l,&dat[i].r,&dat[i].x);
        for(int i=1;i<=n;i++)
        {
            int tmp=0;mx[i]=INF;
            for(int j=1;j<=m;j++)
                if(dat[j].op==1&&i>=dat[j].l&&i<=dat[j].r) 
                    tmp+=dat[j].x;
                else if(dat[j].op==2&&i>=dat[j].l&&i<=dat[j].r)
                    mx[i]=min(mx[i],dat[j].x-tmp);
        }
        for(int i=1;i<=n;i++)
        {
            if(mx[i]==INF) mx[i]=0;
            int tmp=mx[i];
            for(int j=1;j<=m;j++)
                if(dat[j].op==1&&i>=dat[j].l&&i<=dat[j].r) 
                    tmp+=dat[j].x;
                else if(dat[j].op==2&&i>=dat[j].l&&i<=dat[j].r&&tmp==dat[j].x)
                    vis[j]++;
        }
        for(int i=1;i<=m;i++)
            if(dat[i].op==2&&!vis[i]) return puts("NO"),0;
        puts("YES");
        for(int i=1;i<=n;i++) 
            printf("%d ",mx[i]);
        return 0;
    }
    Problem A

    B:

    答案可行性单调,二分答案

    每次判断用$dp[i]$表示到$i$只要要删多少个数,$i$必取

    #include <bits/stdc++.h>
    
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> P;
    const int MAXN=2e3+10;
    int n,k,l,r,dat[MAXN],dp[MAXN];
    
    bool check(int x)
    {
        int ret=n;
        for(int i=1;i<=n;i++) dp[i]=i-1;
        for(int i=2;i<=n;i++)
            for(int j=1;j<i;j++)
                if(abs(dat[i]-dat[j])<=1ll*x*(i-j))
                    dp[i]=min(dp[i],dp[j]+i-j-1);
        for(int i=1;i<=n;i++)
            ret=min(ret,dp[i]+n-i);
        return ret<=k;
    }
    
    int main()
    {
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++) scanf("%d",&dat[i]);
        l=0;r=2e9;
        while(l<=r)
        {//注意爆long long
            int mid=l/2+r/2+(l%2+r%2)/2;
            if(check(mid)) r=mid-1;
            else l=mid+1;
        }
        printf("%d",l);
        return 0;
    }
    Problem B

    $i$必取这个条件一定要加,否则无法转移

    同时注意二分时$l+r$可能爆$longlong$

    C:

    想到从前往后$dp$,每次按以$i$为左端点时对答案的贡献转移

    但这样在$t[i]=s[i]$时是后项相关的,不符合$dp$要求

    因此要将$t[i]=s[i]$合并在$t[i]>s[i]$中计算,$t[i]>s[i]$时的贡献变为$(pre+1)*(n-i+1)$

    $dp[i][j]$:以前$i$位为左端点结果为$j$的方案数,分$t[i]>s[i]$与$t[i]<s[i]$枚举$pre$转移

    #include <bits/stdc++.h>
    
    using namespace std;
    typedef long long ll;
    const int MAXN=2e3+10,MOD=1e9+7;
    int n,k;char s[MAXN];
    ll pre[MAXN][MAXN],dp[MAXN][MAXN];
    
    int main()
    {
        scanf("%d%d%s",&n,&k,s+1);
        dp[0][0]=pre[0][0]=1;
        for(int i=1;i<=n;i++)
            for(int j=0;j<=k;j++)
            {
                dp[i][j]=pre[i-1][j]*(s[i]-'a')%MOD;
                for(int k=0;(k+1)*(n-i+1)<=j&&k<i;k++)
                    (dp[i][j]+=dp[i-k-1][j-(k+1)*(n-i+1)]*('z'-s[i]))%=MOD;
                pre[i][j]=(pre[i-1][j]+dp[i][j])%MOD;
            }
        printf("%lld",pre[n][k]);
        return 0;
    }
    Problem C
  • 相关阅读:
    iOS优秀博文合集
    iOS优化策略
    iOS编码规范
    二维码
    Objective-C Http常用API 同步请求与异步请求
    iOS开发之Runtime函数
    ios开发之常用宏的定义
    iOS开发之动画编程的几种方法
    iOS开发之常用第三方框架(下载地址,使用方法,总结)
    使用OC和swift创建系统自带的刷新界面
  • 原文地址:https://www.cnblogs.com/newera/p/9553490.html
Copyright © 2011-2022 走看看