• Codeforces Round #744 (Div. 3) (CF1579) 题解


    CF1579E2. Array Optimization by Deque
    题意
    给一组数据放入deque中(可以从前面放,也可以从后面),要使逆序数最少。
    解法
    可以发现,前面的放入顺序对后面的每一个数产生的逆序数没有影响。所以直接贪心,每个数选择最好的位置放进去。注意要离散化。

    #include <bits/stdc++.h>
    #define int long long
    #define lb(x) (x&(-x))
    #define For(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    const int N=800005;
    int t,n,a[N],tt[N],f[N];
    void add(int x) {
        for(int i=x;i<=N;i+=lb(i)) f[i]++;
    }
    int query(int x) {
        int ans=0;
        for(int i=x;i;i-=lb(i)) ans+=f[i];
        return ans;
    }
    signed main() {
        cin>>t;
        while(t--) {
            memset(f,0,sizeof f);
            cin>>n;
            For(i,1,n) {
            	cin>>a[i];
    			tt[i]=a[i];	
            }
            sort(tt+1,tt+n+1);
            int m=unique(tt+1,tt+n+1)-tt-1;
            For(i,1,n) a[i]=lower_bound(tt+1,tt+m+1,a[i])-tt;
            int ans=0;
            For(i,1,n) {
                ans+=min(query(a[i]-1ll),(i-1)-query(a[i]));
                add(a[i]);
            }
    		cout<<ans<<'
    ';
        }
    }
    //3 5 5 6 7 9
    //adding 6
    //front->3 back->2
    
    

    CF1579F. Array Stabilization (AND version)
    题意
    有一个01数组,给出d,每次操作即把原先的数组与数据右移d位后的数组进行and操作。问几轮后数据变为全0。
    解法
    考虑一个1变成0的情况,即a[i]=1 && a[i+d]=0。所以用i+d→i的顺序进行BFS,搜索总层数即为答案。

    #include <bits/stdc++.h>
    #define For(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    const int N=1000005;
    int t,n,d,mx;
    struct node {
        int v,s;
    } a[N];
    queue <int> q;
    signed main() {
        cin>>t;
        while(t--) {
            memset(a,0,sizeof a);
            cin>>n>>d;
            For(i,0,n-1) cin>>a[i].v;
            while(!q.empty()) q.pop();
            mx=0;
            For(i,0,n-1) if(a[i].v==0 && a[(i-d+n)%n].v==1) {
                q.push(i);
            }
            while(!q.empty()) {
                int now=q.front();
                q.pop();
                if(a[(now-d+n)%n].v==1) {
                    a[(now-d+n)%n]=(node) {0,a[now].s+1};
                    q.push((now-d+n)%n);
                    mx=max(mx,a[now].s+1);
                }
            }
            bool flag=1;
            For(i,0,n-1) if(a[i].v==1) flag=0;
            if(flag==1) cout<<mx<<'
    '; else puts("-1");
        }
        return 0;
    }
    

    CF1579G. Minimal Coverage
    题意
    有一些棍子,前后相连,每一根可以向左或向右,求覆盖的长度的最小值。
    解法
    来源

    几个当时疑惑的点再写一下:
    倒数第四行的max(dp[i][l]-a[i+1],0)可以看成与上面的左边界max(l-a[i+1],0)一样的道理。就是说:如果现在使用的数据超出了原本最优解限定的范围,就默认它现在已经是极左(右)点。

    //f[i][j]:到i位且当前距离左端点j时,到右端点的长度
    //太难了太难了 动态规划一生之敌
    #include <bits/stdc++.h>
    #define For(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    const int N=10005;
    int t,n,a[N],f[N][2005],mx;
    signed main() {
        cin>>t;
        while(t--) {
            cin>>n;
            mx=0;
            For(i,1,n) {cin>>a[i]; mx=max(mx,a[i]);}
            For(i,1,n) For(j,0,2*mx) f[i][j]=0x3f3f3f3f;
            f[0][0]=0;
            For(i,0,n-1) For(j,0,2*mx) {
                f[i+1][max(0,j-a[i+1])]=
                    min(f[i+1][max(0,j-a[i+1])],f[i][j]+a[i+1]);
                if(j+a[i+1]<=2000) f[i+1][j+a[i+1]]=
                    min(f[i+1][j+a[i+1]],max(f[i][j]-a[i+1],0));
            }
            int ans=0x3f3f3f3f;
            For(i,0,2*mx) ans=min(ans,i+f[n][i]);
            cout<<ans<<'
    ';
            
        }
        return 0;
    }
    
    人间没有永恒的夜晚,世界没有永恒的冬天
  • 相关阅读:
    python的配置
    SSI服务端包含技术
    IDEA使用过程中常见小问题
    IDEA配置maven,jdk,编码
    不使用SwitchHosts修改C:WindowsSystem32driversetchosts文件
    webstorm打开一个门户工程流程
    安装nginx流程
    webstorm配置node.js
    Linux的inode与block
    使用vsftpd 搭建ftp服务
  • 原文地址:https://www.cnblogs.com/wky32768/p/15505371.html
Copyright © 2020-2023  润新知