• Codeforces Round #384 (Div. 2) //复习状压... 罚时爆炸 BOOM _DONE


    不想欠题了..... 多打打CF才知道自己智商不足啊...

    A. Vladik and flights

    给你一个01串  相同之间随便飞 没有费用 不同的飞需要费用为  abs i-j   

    真是题意杀啊,,,实际上我们只考虑01转换的代价一定为1如果目的地和起点相同  费用为0 

    不相同  肯定为1  因为0旁边必然有1

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <set>
    #include <string.h>
    #include <cctype>
    #include <climits>
    using namespace std;
    typedef long long ll;
    template <class T>
    inline bool r(T &ret) 
    {
        char c; 
        int sgn;
        if (c = getchar(), c == EOF) 
        {
            return 0; //EOF 
        }
        while (c != '-' && (c < '0' || c > '9')) 
        {
            c = getchar(); 
        }
        sgn = (c == '-') ? -1 : 1;
        ret = (c == '-') ? 0 : (c - '0'); 
        while (c = getchar(), c >= '0' && c <= '9') 
        {
            ret = ret * 10 + (c - '0'); 
        }
        ret *= sgn;
        return 1;
    }
    const int N = 1e5+10;
    char ch[N];
    int main()
    {
        int n;
        r(n);
        int x,y;
        r(x),r(y);
        scanf("%s",ch+1);
        if(ch[x]==ch[y])
        {
            printf("0
    ");
        }
        else{
            printf("1
    ");
        }
        return 0;
    }
    zz

    B. Chloe and the sequence

    给一个n,然后按照 1  121 1213121 的第n个串

    那么肯定是二分n次必得....  赛场拿python写的   (L+R)没加括号T1

    n,k = map(int, input().split())
    def calc(k):
        L = 0
        R = 2**n
        M = L+R//2
        ans = 0
        while(k!=M):
            if(k>M):
                L = M
            else:
                R = M
            M = (L+R)//2
            ans+=1
        print(n-ans)
    calc(k)
    Py

    C. Vladik and fractions

    问2/n能不能由1/a+1/b+1/c(a,b,c互不相同) 太粗心,没看到互不相同 wa1 没特判1 被hack 1

    手推 a = n b = n+1 c = n*(n+1)

    n=1分不出的

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <set>
    #include <string.h>
    #include <cctype>
    #include <climits>
    using namespace std;
    typedef long long ll;
    template <class T>
    inline bool r(T &ret) 
    {
        char c; 
        int sgn;
        if (c = getchar(), c == EOF) 
        {
            return 0; //EOF 
        }
        while (c != '-' && (c < '0' || c > '9')) 
        {
            c = getchar(); 
        }
        sgn = (c == '-') ? -1 : 1;
        ret = (c == '-') ? 0 : (c - '0'); 
        while (c = getchar(), c >= '0' && c <= '9') 
        {
            ret = ret * 10 + (c - '0'); 
        }
        ret *= sgn;
        return 1;
    }
    
    int main()
    {
        int n;
        r(n);
        if(n==1) printf("-1");
        else printf("%d %d %d
    ",n,n+1,n*(n+1));
        return 0;
    }
    AC

    D.Chloe and pleasant prizes 

    带权有根树  选两个不相交子树的之和最大,裸DFS。

    吐槽一下自己奇差无比的代码。。。两个dfs才完成任务...

    还因为各种写搓  wa了3次

    #include <stdio.h>
    #include <iostream>
    #include <algorithm>
    #include <limits.h>
    #include <vector>
    using namespace std;
    typedef long long ll;
    const int N = 2e5+10;
    vector<int>g[N];
    ll sum[N];
    ll son[N];
    int a[N];
    void push(int x,int y){g[x].push_back(y);g[y].push_back(x);}
    bool flag = true;
    void UMAX(ll& a,ll& b,ll c){
        if(c>a)
        {
            b = a;
            a = c;
        }
        else{
            if(c>=b)
            {
                b = c;
            }
        }
    }
    ll dfs(int now,int pre)
    {
        sum[now] += a[now];
        
        bool mk = true;
        for(int i=0;i<g[now].size();i++)
        {
            if(g[now][i]==pre) continue;
            ll val = dfs(g[now][i],now);
            sum[now] += val;
            if(!mk)son[now] = max(son[now],son[g[now][i]]);
            else{
                mk = false;
                son[now] = son[g[now][i]];
            }
        }
        if(mk)son[now] = a[now]; 
        son[now] = max(son[now],sum[now]);
        return sum[now];
    }
    ll ans = LONG_LONG_MIN;
    void F(int now,int pre)
    {
        //cout<<now<<endl;
        ll a = LONG_LONG_MIN;
        ll b = LONG_LONG_MIN;
        for(int i=0;i<g[now].size();i++)
        {
            if(pre==g[now][i]) continue;
            UMAX(a,b,son[g[now][i]]);
            F(g[now][i],now);
        }
        //if(now==4) cout<<a<<"  "<<b<<endl;
        if(b!=LONG_LONG_MIN)ans = max(ans,a+b);
    }
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
        }
        int x,y;
        for(int i=1;i<n;i++)
        {
            scanf("%d%d",&x,&y);
            push(x,y);
        }
        dfs(1,-1);
        /*
        for(int i=1;i<=n;i++)
            printf("%d	",i);
        printf("
    ");
        for(int i=1;i<=n;i++)
            printf("%I64d	",sum[i]);
        printf("
    ");
        for(int i=1;i<=n;i++)
            printf("%I64d	",son[i]);
        printf("
    ");
        //*/
        F(1,-1);
        if(ans==LONG_LONG_MIN) 
            printf("Impossible
    ");
        else{
            printf("%I64d
    ",ans);
        }
        return 0;
    }
    AC代码

    贴一下陈老师的代码....

    #include<cstdio>
    #include<algorithm>
    typedef long long ll;
    const int N=200010;
    const ll inf=1LL<<60;
    int n,i,x,y,a[N],g[N],v[N<<1],nxt[N<<1],ed;ll f[N],dp[N],ans=-inf;
    inline void add(int x,int y){v[++ed]=y;nxt[ed]=g[x];g[x]=ed;}
    void dfs(int x,int y){
      f[x]=a[x];
      dp[x]=-inf;
      for(int i=g[x];i;i=nxt[i]){
        int u=v[i];
        if(u==y)continue;
        dfs(u,x);
        f[x]+=f[u];
        if(dp[x]>-inf)ans=std::max(ans,dp[x]+dp[u]);
        dp[x]=std::max(dp[x],dp[u]);
      }
      dp[x]=std::max(dp[x],f[x]);
    }
    int main(){
      scanf("%d",&n);
      for(i=1;i<=n;i++)scanf("%d",&a[i]);
      for(i=1;i<n;i++)scanf("%d%d",&x,&y),add(x,y),add(y,x);
      dfs(1,0);
      if(ans>-inf)printf("%I64d",ans);else puts("Impossible");
    }
    claris
     
     

    E. Vladik and cards

    题意给以一个1-8组成的串  选出一个子串(在原串中可以不连续)  选出来的串 每个数相同的一定相邻  而且 每种数的个数相差不超过1

    比赛时只想到DFS的解,后来证实是错的

    后来看别人的代码一脸蒙=。=... 后来一神说了两个数组的作用才明白...就这样   参考claris的写法

    而且....

    这样也写了好久  而且还少更新状态   长度可以为0...... 

    #include<cstdio>
    #include<cstring>
    void Min(int &a,int b) {if(a>b) a=b;}
    void Max(int &a,int b) {if(a<b) a=b;}
    const int maxn = 1010;
    int cnt[10];
    int g[maxn][maxn][10];//i j k 
    int dp[256][10];//i 选择方案  j 代表  长度的集合个数   长度最多n/8+1 
    int val[maxn];
    int n;
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&val[i]),val[i]--;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n+5;j++)
                for(int k=0;k<=8;k++) g[i][j][k] = maxn;
            memset(cnt,0,sizeof(cnt));
            for(int j=i;j<=n;j++)
                g[i][++cnt[val[j]]][val[j]] = j; 
        }
        int ans = 0;
        for(int i=0;i*8<=n;i++)//长度 
        {
            for(int j=0;j<256;j++)
                for(int k=0;k<=8;k++)
                    dp[j][k] = maxn;
            dp[0][0] = 1; //从1开始 
            for(int j=0;j<256;j++)//选择方案 
            {
                for(int k=0;k<=8;k++)// 
                {
                    if(dp[j][k]>n)continue; 
                    for(int l=0;l<8;l++)
                    {
                        if((1<<l)&j) continue;
                        Min(dp[j|(1<<l)][k],g[dp[j][k]][i][l]+1);
                        Min(dp[j|(1<<l)][k+1],g[dp[j][k]][i+1][l]+1);
                    }
                }
            }
            for(int j=0;j<=8;j++) if(dp[255][j]<n+2){
                Max(ans,j+8*i);
            }
        }
        printf("%d
    ",ans);
        return 0;
    } 
    状压DP
  • 相关阅读:
    ubuntu正确输入用户名密码后重复登录界面
    Spring第一个程序
    winrar解压spring出现“路径和文件名总长度必须不能超过 260 个字符!”错误的解决方法
    Spring属性装配之属性类型是另外一个被装载的类
    classpath、path、JAVA_HOME的作用及JAVA环境变量配置
    ubuntu基本命令篇15系统管理time命令中Real,User,Sys概念
    基于linux使用mysql二进制包安装mysql5.5
    shell循环语法
    db笔记本
    shell function
  • 原文地址:https://www.cnblogs.com/Geek-xiyang/p/6183808.html
Copyright © 2020-2023  润新知