• HDU 多校联合第二场


    1001

    不是在为这次比赛找借口。。。我真的想吐嘈一下这道题。。。

    尼嘛!明明是状态dp!非得搞得数据随便贪心都能过!!!过你妹啊!埋头想dp的时候,大约开始十几分钟,刷新了一下。我了个去!快上百了!纯属恶心人吗?! 吐嘈完毕 -_-!

     

    状态dp:1 <= N <= 20,最多20位,完全可以位压缩。预处理一下hp_sum[i] (i = 010111...101),表示i的二进制中所有为1的位置,他们的hp之和。 f[i] (i = 010111...101)表示i的二进制中所有为1的位置被干掉话费的最小代价

    f[ i|(1<< j) ] = max(f[ i|(1<< j) ], f[i] + hp_sum[ i|(1<<j) ]*p[j].Dpi);

    1002

    对数据用数状数组预处理,当时根本就没有任何思路。。。任何思路。。。赛后各种水过。。。居然可以蹭数据。。。。枚举出来一个约数,去你妹的!

    大概过程是对x,y进行离散话,然后按离散化以后的值作为位置,原值作为value加到数状数组里边。

    统计到X时,比X小的数的和为sumx,个数为numx,所以时间为X*numx - sumx。同样,比mx大的数也能统计出来(总数减掉sumx)

    同理对Y的在数状数组,也可以得到sumy, numy...

    用到四颗数状数组:分别用来计算 sumx, numx, sumy, numy。

    View Code
    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <vector>
    #include <cstring>
    #include <algorithm>
    #include <string>
    #include <set>
    #include <ctime>
    #include <queue>
    #include <map>
    #include <sstream>
    
    #define CL(arr, val)    memset(arr, val, sizeof(arr))
    #define REP(i, n)       for((i) = 0; (i) < (n); ++(i))
    #define FOR(i, l, h)    for((i) = (l); (i) <= (h); ++(i))
    #define FORD(i, h, l)   for((i) = (h); (i) >= (l); --(i))
    #define L(x)    (x) << 1
    #define R(x)    (x) << 1 | 1
    #define MID(l, r)   (l + r) >> 1
    #define Min(x, y)   x < y ? x : y
    #define Max(x, y)   x < y ? y : x
    #define E(x)    (1 << (x))
    #define iabs(x)  ((x) > 0 ? (x) : -(x))
    
    typedef long long LL;
    const int eps = 1e-8;
    const LL inf = 1e15;
    
    using namespace std;
    
    const int N = 100010;
    
    struct node {
        int x;
        int y;
    }p[N];
    
    LL cx[N], cy[N];
    LL Nx[N], Ny[N];
    int tx[N], ty[N], n;
    
    
    int lowbit(int i) {
        return i&(-i);
    }
    void add(LL c[], int i, LL val) {
        while(i <= n) {
            c[i] += val;
            i += lowbit(i);
        }
    }
    
    LL sum(LL c[], int i) {
        LL ret = 0;
        while(i > 0) {
            ret += c[i];
            i -= lowbit(i);
        }
        return ret;
    }
    
    int findx(int x) {
        int l = 1, r = n, mid;
        while(l <= r) {
            mid = (l + r) >> 1;
            if(tx[mid] == x)   return mid;
            else if(tx[mid] < x)   l = mid + 1;
            else    r = mid - 1;
        }
        return -1;
    }
    
    int findy(int x) {
        int l = 1, r = n, mid;
        while(l <= r) {
            mid = (l + r) >> 1;
            if(ty[mid] == x)   return mid;
            else if(ty[mid] < x)   l = mid + 1;
            else    r = mid - 1;
        }
        return -1;
    }
    
    void init() {
        CL(cx, 0); CL(cy, 0);
        CL(Nx, 0); CL(Ny, 0);
    }
    
    int main() {
        //freopen("data.in", "r", stdin);
    
        int t, i;
    
        int x, y;
        LL tolx, toly;
        LL sumx, sumy;
        LL numx, numy;
        LL tmpx, tmpy;
        LL ans;
    
        scanf("%d", &t);
        while(t--) {
            init();
    
            scanf("%d", &n);
            ans = inf;
            tolx = toly = 0;
            for(i = 1; i <= n; ++i) {
                scanf("%d%d", tx + i, ty + i);
    
                p[i].x = tx[i], p[i].y = ty[i];
                tolx += tx[i], toly += ty[i];
            }
    
            sort(tx + 1, tx + n + 1);
            sort(ty + 1, ty + n + 1);
    
            for(i = 1; i <= n; ++i) {
                x = findx(p[i].x);
                y = findy(p[i].y);
    
                add(cx, x, p[i].x); add(cy, y, p[i].y);
                add(Nx, x, 1);   add(Ny, y, 1);
            }
            //printf("tolx = %lld, toly = %lld\n",tolx,toly);
            for(i = 1; i <= n; ++i) {
                x = findx(p[i].x);
                y = findy(p[i].y);
                sumx = sum(cx, x) - p[i].x; sumy = sum(cy, y) - p[i].y;
    
                numx = sum(Nx, x) - 1; numy = sum(Ny, y) - 1;
    
                //printf("sumx = %lld, sumy = %lld, numx = %lld, numy = %lld\n", sumx, sumy, numx, numy);
                tmpx = (numx*p[i].x - sumx) + (tolx - sumx - p[i].x*(n - numx));
                tmpy = (numy*p[i].y - sumy) + (toly - sumy - p[i].y*(n - numy));
    
                //printf("tmpx(%lld) + tmpy(%lld) = %lld\n\n", tmpx, tmpy, tmpx + tmpy);
                ans = Min(ans, tmpx + tmpy);
    
            }
            cout << ans << endl;
        }
        return 0;
    }

    1003

    各种蹭数据,真的好无聊。。。标程没看懂

    找所有x的中点,所有y的中点,按到中点的距离排序。。。枚举前100个点。这都能蹭过去。。。。

    1004

    对于这题我只能说我是弱b。。。kruskal改动一下,按边权从大到小排序。。。。并查集维护,要删除的两个点不能在一个集合里边。。。

    View Code
    const int N = 100010;
    
    int parent[N];
    
    struct node {
        int x;
        int y;
        int d;
    } p[N];
    
    int n, k;
    bool del[N];
    
    bool cmp(node a, node b) {
        return a.d > b.d;
    }
    
    int find(int x) {
        int k = x, r = x, j;
        while(r != parent[r])   {
            if(del[r])  del[parent[r]] = true;
            r = parent[r];
        }
    
        while(k != r) {
            j = parent[k];
            parent[k] = r;
            k = j;
        }
        return r;
    }
    
    LL solve() {
        LL cnt = 0;
        int x, y;
        for(int i = 0; i < n - 1; ++i) {
            x = find(p[i].x);
            y = find(p[i].y);
            if(x == y)  continue;
            if(del[x] && del[y])   {cnt += LL(p[i].d); continue;}
            parent[y] = x;
            if(del[y])  del[x] = true;
            if(del[x])  del[y] = true;
        }
        return cnt;
    }
    
    void init() {
        CL(del, false);
        for(int i = 0; i <= n; ++i)     parent[i] = i;
    }
    
    int main() {
        //freopen("data.in", "r", stdin);
    
        int t, i, x;
        scanf("%d", &t);
        while(t--) {
            scanf("%d%d", &n, &k);
            init();
            for(i = 0; i < n - 1; ++i) {
                scanf("%d%d%d", &p[i].x, &p[i].y, &p[i].d);
            }
            for(i = 0; i < k; ++i) {
                scanf("%d", &x);
                del[x] = true;
            }
            sort(p, p + n - 1, cmp);
            cout << solve() << endl;
        }
        return 0;
    }

      

        

    1009

    bfs 爆搞的,记录每个节点的最大剩余电量,防止有环的时候死循环

    View Code
    const int N = 2500010;
    const int M = 50010;
    
    struct node {
        int to;
        int next;
        double val;
    } g[N];
    
    int head[M], t;
    double val[M];
    
    void init() {
        CL(head, -1); t = 0;
    }
    
    void add(int u, int v, double w) {
        g[t].to = v; g[t].val = w; g[t].next = head[u];
        head[u] = t++;
    }
    
    void bfs(int s, double m) {
        val[s] = m;
        queue<int> q;
        q.push(s);
    
        int i, u, v;
        double w;
    
        while(!q.empty()) {
            u = q.front(); q.pop();
            for(i = head[u]; i != -1; i = g[i].next) {
                v = g[i].to;
                w = val[u]*(100.0 - g[i].val)/100.0;
                if(w > val[v]) {
                    val[v] = w;
                    q.push(v);
                }
            }
        }
    }
    
    int main() {
        //freopen("data.in", "r", stdin);
    
        int n, t, i, x;
        double y;
        while(~scanf("%d", &n)) {
            init();
            for(i = 1; i <= n; ++i) {
                scanf("%d", &t);
                while(t--) {
                    scanf("%d%lf", &x, &y);
                    add(i, x, y);
                }
                val[i] = -1;
            }
            scanf("%d%d%lf", &i, &x, &y);
            bfs(i, y);
            if(val[i] == -1)    puts("IMPOSSIBLE!");
            else    printf("%.2f\n", y - val[x]);
        }
        return 0;
    }

           

  • 相关阅读:
    学习Vue CLI 3.x版本的安装以及创建项目
    Java中同一线程中的对象hashcode一样
    Java中线程范围内共享问题
    Java中的线程池模拟
    java中的Switch
    string、stringbuffer、stringbuild的时间性能对比
    Java中lock上锁 unlock解锁
    java中的三目运算
    Java中的Instanceof
    一个简单的for循环
  • 原文地址:https://www.cnblogs.com/vongang/p/2611823.html
Copyright © 2020-2023  润新知