zoukankan      html  css  js  c++  java
  • Codeforces Round #584

    E2. Rotate Columns (hard version)

    题意:有一个n行m列的矩阵 每一列可以任意旋转平移  问经过操作后每一行的最大值能为多少

     注意到n非常小  m很大  

    首先可以优化m   显然只要考虑最大值最大的n列即可

    所以就转化为了一个n行n列的矩阵 

    可以考虑状压dp 

    注意要维护三个数组

    #include<bits/stdc++.h>
    using namespace std;
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define ll long long
    #define see(x) (cerr<<(#x)<<'='<<(x)<<endl)
    #define inf 0x3f3f3f3f
    #define CLR(A,v)  memset(A,v,sizeof A)
    /////////////////////////////////////
    const int N=1e5+10;
    int n,m,a[20][2000+10],id[N],maxx[N],dp[1<<13],olddp[1<<13],temp[1<<13];
     
    int main()
    {
        int cas;cin>>cas;
        while(cas--)
        {   
            memset(dp,0,sizeof dp);
            memset(olddp,0,sizeof olddp);
            memset(maxx,0,sizeof maxx);
            scanf("%d%d",&n,&m);
            rep(i,0,n-1)rep(j,1,m)
            scanf("%d",&a[i][j]),maxx[j]=max(maxx[j],a[i][j]);
            rep(i,1,m)id[i]=i;
            sort(id+1,id+1+m,[](int x,int y){return maxx[x]>maxx[y];});
            m=min(m,n);
              //rep(i,1,m)printf("%lld  ",maxx[id[i]]);cout<<endl;
            rep(i,1,m)
            {   
                memcpy(olddp,dp,sizeof dp);
                memset(temp,0,sizeof temp);
                for(int state=0;state<(1<<n);++state){   
                    for(int k=0;k<n;k++)
                    {
                        int sum=0;
                        for(int now=0;now<n;++now)
                        if( 1&(state>>now))sum+=a[(now+k)%n][id[i]];
                        temp[state]=max(temp[state],sum);
                    }
                    for(int state2=state;state2<(1<<n); state2= ((state2+1)|state) )
                    dp[state2]=max(dp[state2],temp[state]+olddp[state2^state]);
                }
            }
            printf("%d
    ",dp[(1<<n)-1]);
        }
        return 0;
    }
    View Code

    F. Koala and Notebook

    题意:有n个点 m条有向边 边权为边的编号  

    输出1到 2-n的“最短路” (最短路为经过边的边权组合而成的最小数)

    显然要贪心得遍历  但是其结果和长度有关  长度越小数字肯定小  然后比字典序

    一些边的编号长一些边的编号短  所以首先一定要进行预处理  

    建立虚点  每条边的权值小于10 所以控制了长度  那么就可以进行bfs 了  第一个到的肯定是长度最小的 

    并且要进行贪心的bfs  

    注意vector的使用!!!

    一开始没用vector  那么 234 256的情况没法 如果先跑了256了答案就会出错

    设置成一组一组即可避免错误

    #include<bits/stdc++.h>
    using namespace std;
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define ll long long
    #define see(x) (cerr<<(#x)<<'='<<(x)<<endl)
    #define inf 0x3f3f3f3f
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    const int N= 2e6+5 ;
    const ll mod=1e9+7;
    vector<int>edge[N][11];
    int n,m,pos,vis[N],v;
    ll ans[N];
    inline void add(int a,int b,int c)
    {
        for(;c>9;c/=10)edge[++pos][c%10].push_back(b),b=pos;
        edge[a][c].push_back(b);
    }
    inline void bfs()
    {
        queue< vector<int> >q;
        vector<int>u;
        u.push_back(1);
        vis[1]=1;q.push(u);
        while(!q.empty())
        {
            u=q.front();
            q.pop();
            rep(i,0,9)
            {   
                vector<int> temp;
                for(auto v:u)
                for(auto w:edge[v][i])if(!vis[w])
                vis[w]=1,ans[w]=(ans[v]*10+i)%mod,temp.push_back(w);
                if(temp.size())q.push(temp);
            }
        }
    }
     
    int main()
    {
        cin>>n>>m;pos=n;int u,v;
        rep(i,1,m)scanf("%d%d",&u,&v),add(u,v,i),add(v,u,i);
        bfs();
        rep(i,2,n)printf("%lld
    ",ans[i]);
        return 0;
    }
    View Code

    G1. Into Blocks (easy version)

    题意: 给定一个数字序列a  将一个数字(所有)变为另一个数字的代价为这个数字的个数

    问构成good序列的最小代价

    good序列  如果序列中两个数相同那么他们之间的数字和他们相同

    代码很好懂 妙呀

    #include<bits/stdc++.h>
    using namespace std;
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define ll long long
    #define see(x) (cerr<<(#x)<<'='<<(x)<<endl)
    #define inf 0x3f3f3f3f
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    const int N=2e6+10;
     
    int last[N],cnt[N],a[N],num,ans;
    int main()
    {
        int n,q,l,r;
        cin>>n>>q;
        rep(i,1,n)
        scanf("%d",&a[i]),last[a[i]]=i,cnt[a[i]]++;
     
        rep(i,1,n)
        {
            l=i;r=last[a[i]];num=cnt[a[i]];
            while(i<r)i++,r=max(r,last[a[i]]),num=max(num,cnt[a[i]]);
            ans+=r-l+1-num;
        }
        cout<<ans;
     
        return 0;
    }
    View Code
  • 相关阅读:
    docker常用命令
    redis常用命令
    Spring boot redis自增编号控制 踩坑
    docker 安装 nginx
    Linux常用命令记录
    leetcode-120. 三角形最小路径和
    leetcode-229.求众数(二)
    leetcode-169.求众数
    冒泡排序学习笔记
    快速排序学习笔记
  • 原文地址:https://www.cnblogs.com/bxd123/p/11585373.html
Copyright © 2011-2022 走看看