zoukankan      html  css  js  c++  java
  • 8.14 Round 1

    心态爆炸——

    T2小细节出大锅,T3没写%lld,75pts->15pts

    T1:https://www.luogu.org/problem/T94043

    MST,USACO有原题

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<climits>
    #include<map>
    #include<queue>
    #include<cmath>
    using namespace std;
    #define O(x) cout << #x << " " << x << endl;
    #define B cout << "breakpoint" << endl;
    #define clr(a) memset(a,0,sizeof(a));
    typedef long long ll;
    inline int read()
    {
        int ans = 0,op = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9')
        {
            if(ch == '-') op = -1;
            ch = getchar();
        }
        while(ch >= '0' && ch <= '9')
        {
            (ans *= 10) += ch - '0';
            ch = getchar();
        }
        return ans * op;
    }
    const int maxm = 2e6 + 5; 
    const int maxn = 1006;    
    struct egde
    {
        int u,v,w;
        bool operator < (const egde& b) const
        {
            return  w < b.w;
        }
    }e[maxm];
    struct node
    {
        int x,y;
    }a[maxn];
    int tot;
    int n,A,b;
    void adde(int u,int v,int w) { e[++tot].u = u; e[tot].v = v,e[tot].w = w; }
    int par[maxn],rk[maxn];
    void init() { for(int i = 1;i <= maxn - 5;i++) par[i] = i; }
    inline int find(int x) { return x == par[x] ? x : par[x] = find(par[x]); }
    inline void merge(int x,int y)
    {
        x = find(x); y = find(y);
        if(x == y) return;
        if(rk[x] < rk[y]) par[x] = y;
        else par[y] = x;
        if(rk[x] == rk[y]) rk[x]++;
    }
    int cnt;
    ll ans;
    void kruskal()
    {
        sort(e + 1,e + 1 + tot);
        for(int i = 1;i <= tot;i++)
        {
            int u = find(e[i].u),v = find(e[i].v);
            if(u == v) continue;
            merge(u,v); ans = ans + 1ll * e[i].w; cnt++;
            if(cnt == n) break;
        }
    }
    int main()
    {
        freopen("pupil.in","r",stdin);
        freopen("pupil.out","w",stdout);
        init();
        n = read(),A = read(),b = read();
        for(int i = 1;i <= n;i++) 
        {
            adde(i,n + 1,A);
            a[i].x = read(),a[i].y = read();
            for(int j = 1;j < i;j++)
                {
                    int d = abs(a[i].x - a[j].x) + abs(a[i].y - a[j].y);
                    adde(i,j,d * b);
                }
        }
        kruskal();
        printf("%lld",ans);
    }
    View Code

    T2:https://www.luogu.org/problem/T94044

    线段覆盖,细节出锅

    pos在排序前后对应的线段肯定改变了,没注意到,直接GG

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<climits>
    #include<map>
    #include<queue>
    #include<cmath>
    using namespace std;
    #define clr(a) memset(a,0,sizeof(a));
    typedef long long ll;
    inline int read()
    {
        int ans = 0,op = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9')
        {
            if(ch == '-') op = -1;
            ch = getchar();
        }
        while(ch >= '0' && ch <= '9')
        {
            (ans *= 10) += ch - '0';
            ch = getchar();
        }
        return ans * op;
    }
    const int maxn = 5e5 + 5;
    struct node
    {
        int l,r,id;
        bool operator < (const node& b) const
        {
            if(l == b.l) return r > b.r;
            return l < b.l;
        }
    }a[maxn];
    int n,pos,ans = 1;
    int main()
    {
        freopen("cat.in","r",stdin);
        freopen("cat.out","w",stdout);
        n = read();
        for(int i = 1;i <= n;i++)
        {
            int x = read();
            a[i].l = i - x,a[i].r = i + x,a[i].id = i;
            if(a[i].l <= 1 && a[i].r > a[pos].r) pos = i;
        }
        sort(a + 1,a + 1 + n);
        /*for(int i = 1;i <= n;i++)
        printf("%d %d %d
    ",a[i].l,a[i].r,a[i].id); */
        for(int i = 1;i <= n;i++) if(a[i].id == pos) { pos = i; break; }
        int i = pos + 1;
        while(i <= n)
        {
            //O(a[i].r); //O(a[pos].r);
            int tpos = 0;
            while(a[i].l <= a[pos].r + 1 && i <= n) 
            {
                if(a[i].r > a[tpos].r) tpos = i;
                i++;
            }
            pos = tpos,ans++;
            if(a[pos].r >= n) break;
        }
        printf("%d",ans);
    }
    /*
    10
    0 0 0 0 0 0 0 0 0 0 */
    View Code

    T3:https://www.luogu.org/problem/T94046

    斜率优化,70pts做法

    100pts就在优化的时候把dp数组带上

    输出long long的时候一定要用%lld!!!!!不论是否超int

    不然在有的评测环境下只有0

    75pts:

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<climits>
    #include<map>
    #include<queue>
    #include<cmath>
    using namespace std;
    #define clr(a) memset(a,0,sizeof(a));
    #define int long long
    typedef long long ll;
    typedef double db;
    inline int read()
    {
        int ans = 0,op = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9')
        {
            if(ch == '-') op = -1;
            ch = getchar();
        }
        while(ch >= '0' && ch <= '9')
        {
            (ans *= 10) += ch - '0';
            ch = getchar();
        }
        return ans * op;
    }
    const int maxn = 1e6 + 5;
    int sum[maxn],d[maxn],a1[maxn],a2[maxn];
    int n,k;
    int totans;
    int q[maxn],head,tail,f[maxn];
    db get_k(int j,int k) {return (sum[j] * d[j] - sum[k] * d[k]) / (sum[j] - sum[k]); } 
    main()
    {
        freopen("life.in","r",stdin);
        freopen("life.out","w",stdout);
        n = read(),k = read();
        for(int i = 1;i <= n;i++)
        {
            a1[i] = read(),a2[i] = read();
            sum[i] = sum[i - 1] + a1[i];
        }
        for(int i = n;i >= 1;i--) d[i] = d[i + 1] + a2[i];
        for(int i = 1;i <= n;i++)
            totans += a1[i] * d[i];
        if(k == 0) { printf("%lld
    ",totans); return 0; }
        if(k == 1)
        {
            int ans = LONG_LONG_MAX,pos = 0;
            for(int i = 1;i <= n;i++)
            {
                int res = totans - sum[i] * d[i];
                if(ans > res) ans = res,pos = i;
            }
            printf("%lld
    ",ans);
            printf("%lld ",pos - 1);
            return 0; 
        } 
        if(k == 2)
        {
            int ans = LONG_LONG_MAX;
            int p1,p2;
                for(int i = 1;i <= n;i++)
                {
                    while(head < tail)
                    {
                        if(get_k(q[head],q[head + 1]) > d[i]) head++;
                        else break;
                    } 
                    while(tail > head)
                    {
                        if(get_k(i,q[tail]) > get_k(q[tail],q[tail - 1])) tail--;
                        else break;
                    }
                    q[++tail] = i;
                    int j = q[head];
                    int res = totans - d[i] * (sum[i] - sum[j]) - d[j] * sum[j];
                    if(ans > res) ans = res,p1 = j,p2 = i;
                }
                //if(p1 > p2) swap(p1,p2);
                printf("%lld
    ",ans);
                printf("%lld %lld ",p1 - 1,p2 - 1);
                puts("");
                return 0;
        }
        if(k == 3)
        {
            int ans = LONG_LONG_MAX;
            int p1,p2,p3;
            for(int i = 1;i <= n;i++)
                for(int j = i + 1;j <= n;j++)
                    for(int k = j + 1;k <= n;k++)
                    {
                        int res = totans - d[i] * sum[i] - d[j] * (sum[j] - sum[i]) - d[k] * (sum[k] - sum[j]);
                        if(ans > res) ans = res,p1 = i,p2 = j,p3 = k;
                    }
            printf("%lld
    ",ans);
            printf("%lld %lld %lld ",p1 - 1,p2 - 1,p3 - 1);
            return 0;
        }
    }
    /*
    4 3
    1 1
    2 2
    3 3
    4 4
    */
                
        
    View Code

    AC:

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<climits>
    #include<map>
    #include<queue>
    #include<cmath>
    using namespace std;
    #define clr(a) memset(a,0,sizeof(a));
    #define int long long
    typedef long long ll;
    typedef double db;
    inline int read()
    {
        int ans = 0,op = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9')
        {
            if(ch == '-') op = -1;
            ch = getchar();
        }
        while(ch >= '0' && ch <= '9')
        {
            (ans *= 10) += ch - '0';
            ch = getchar();
        }
        return ans * op;
    }
    const int maxn = 1e6 + 5;
    int sd[maxn],sw[maxn],a1[maxn],a2[maxn],S[maxn],d[maxn],w[maxn];
    int n,k;
    int totans;
    int q[maxn],head,tail,f[maxn][21],pos[maxn][21],ans[maxn];
    db get_k(int x,int y,int k) 
    { 
        db Y = f[x][k - 1] - f[y][k - 1] + S[x] - S[y],X = sw[x] - sw[y];
        return Y / X; 
    } 
    main()
    {
        freopen("life.in","r",stdin);
        freopen("life.out","w",stdout);
        n = read(),k = read();
        for(int i = 1;i <= n;i++)
        {
            w[i] = read(),d[i] = read();
            sw[i] = sw[i - 1] + w[i];
            sd[i] = sd[i - 1] + d[i - 1];
            S[i] = S[i - 1] + sd[i] * w[i];
        }
        sd[n + 1] = sd[n] + d[n]; sw[n + 1] = sw[n],S[n + 1] = S[n];
        memset(f,0x3f,sizeof(f));
        f[0][0] = 0;
        for(int j = 1;j <= k + 1;j++)
        {
        for(int i = 1;i <= n + 1;i++)
        {
            while(head < tail)
            {
                if(get_k(q[head + 1],q[head],j) <= sd[i]) head++;
                else break;
            } 
            while(tail > head)
            {
                if(get_k(i,q[tail],j) <= get_k(q[tail],q[tail - 1],j)) tail--;
                else break;    
            }
            q[++tail] = i;
            int t = q[head];
            pos[i][j] = t;
            f[i][j] = f[t][j - 1] - sd[i] * sw[t] + S[t] + sd[i] * sw[i] - S[i];
        }
        head = tail = 0;
        }
        printf("%lld
    ",f[n + 1][k + 1]);
        int now = n+1,tt = k+1;
        while(now)
        {
            ans[++ans[0]] = pos[now][tt];
            now = ans[ans[0]],tt--;
        }
        for(int i = ans[0]-1;i>=1;--i)printf("%lld ",ans[i]-1);
    }
    /*
    4 3
    1 1
    2 2
    3 3
    4 4
    */
                
        
    View Code
  • 相关阅读:
    【数据结构】线性表&&顺序表详解和代码实例
    【智能算法】超详细的遗传算法(Genetic Algorithm)解析和TSP求解代码详解
    【智能算法】用模拟退火(SA, Simulated Annealing)算法解决旅行商问题 (TSP, Traveling Salesman Problem)
    【智能算法】迭代局部搜索(Iterated Local Search, ILS)详解
    10. js时间格式转换
    2. 解决svn working copy locked问题
    1. easyui tree 初始化的两种方式
    10. js截取最后一个斜杠后面的字符串
    2. apache整合tomcat部署集群
    1. apache如何启动
  • 原文地址:https://www.cnblogs.com/LM-LBG/p/11351986.html
Copyright © 2011-2022 走看看