zoukankan      html  css  js  c++  java
  • Game HDU

    Game

    Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 1563    Accepted Submission(s): 664


    Problem Description
    onmylove has invented a game on n × m grids. There is one positive integer on each grid. Now you can take the numbers from the grids to make your final score as high as possible. The way to get score is like
    the following:
    ● At the beginning, the score is 0;
    ● If you take a number which equals to x, the score increase x;
    ● If there appears two neighboring empty grids after you taken the number, then the score should be decreased by 2(x&y). Here x and y are the values used to existed on these two grids. Please pay attention that "neighboring grids" means there exits and only exits one common border between these two grids.

    Since onmylove thinks this problem is too easy, he adds one more rule:
    ● Before you start the game, you are given some positions and the numbers on these positions must be taken away.
    Can you help onmylove to calculate: what's the highest score onmylove can get in the game?
     
    Input
    Multiple input cases. For each case, there are three integers n, m, k in a line.
    n and m describing the size of the grids is n ×m. k means there are k positions of which you must take their numbers. Then following n lines, each contains m numbers, representing the numbers on the n×m grids.Then k lines follow. Each line contains two integers, representing the row and column of one position
    and you must take the number on this position. Also, the rows and columns are counted start from 1.
    Limits: 1 ≤ n, m ≤ 50, 0 ≤ k ≤ n × m, the integer in every gird is not more than 1000.
     
    Output
    For each test case, output the highest score on one line.
     
    Sample Input
    2 2 1 2 2 2 2 1 1 2 2 1 2 7 4 1 1 1
     
    Sample Output
    4 9
    Hint
    As to the second case in Sample Input, onmylove gan get the highest score when calulating like this: 2 + 7 + 4 - 2 × (2&4) - 2 × (2&7) = 13 - 2 × 0 - 2 × 2 = 9.
     
    Author
    onmylove
     
    Source
     
     
    解析:
      棋盘问题的变形 多了点限制
      遇到这种问题就向最小割去想   最小割就是求最小价值损失
      对于预先选定的点 x   如果是白点 则 s 向 x 连一条INF的边  如果是黑点 则 x 向 t 连一条INF的边  因为权值为INF  所以无论怎样 这条边都不会成为割边 所以就能代表这条边已经被选择
      其它的就和棋盘问题一样  只不过相邻的点的边权   加了限制之后 把这条边的权值 由棋盘问题的INF 改为 2 * (w1 & w2)即可
    跑一遍Dinic    然后sum - Dinic
    #include <iostream>
    #include <cstdio>
    #include <sstream>
    #include <cstring>
    #include <map>
    #include <cctype>
    #include <set>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <algorithm>
    #include <cmath>
    #include <bitset>
    #define rap(i, a, n) for(int i=a; i<=n; i++)
    #define rep(i, a, n) for(int i=a; i<n; i++)
    #define lap(i, a, n) for(int i=n; i>=a; i--)
    #define lep(i, a, n) for(int i=n; i>a; i--)
    #define rd(a) scanf("%d", &a)
    #define rlld(a) scanf("%lld", &a)
    #define rc(a) scanf("%c", &a)
    #define rs(a) scanf("%s", a)
    #define rb(a) scanf("%lf", &a)
    #define rf(a) scanf("%f", &a)
    #define pd(a) printf("%d
    ", a)
    #define plld(a) printf("%lld
    ", a)
    #define pc(a) printf("%c
    ", a)
    #define ps(a) printf("%s
    ", a)
    #define MOD 2018
    #define LL long long
    #define ULL unsigned long long
    #define Pair pair<int, int>
    #define mem(a, b) memset(a, b, sizeof(a))
    #define _  ios_base::sync_with_stdio(0),cin.tie(0)
    //freopen("1.txt", "r", stdin);
    using namespace std;
    const int maxn = 1e5 + 10, INF = 0x7fffffff;
    int dir[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
    int n, m, k, s, t;
    int way[55][55], vv[2550][2550];
    int head[maxn], cur[maxn], vis[maxn], d[maxn], cnt, nex[maxn << 1];
    
    struct node
    {
        int u, v, c;
    }Node[maxn << 1];
    
    void add_(int u, int v, int c)
    {
        Node[cnt].u = u;
        Node[cnt].v = v;
        Node[cnt].c = c;
        nex[cnt] = head[u];
        head[u] = cnt++;
    }
    
    void add(int u, int v, int c)
    {
        add_(u, v, c);
        add_(v, u, 0);
    }
    
    bool bfs()
    {
        queue<int> Q;
        mem(d, 0);
        Q.push(s);
        d[s] = 1;
        while(!Q.empty())
        {
            int u = Q.front(); Q.pop();
            for(int i = head[u]; i != -1; i = nex[i])
            {
                int v = Node[i].v;
                if(!d[v] && Node[i].c > 0)
                {
                    d[v] = d[u] + 1;
                    Q.push(v);
                    if(v == t) return 1;
                }
            }
        }
        return d[t] != 0;
    }
    
    int dfs(int u, int cap)
    {
        int ret = 0;
        if(u == t || cap == 0)
            return cap;
        for(int &i = cur[u]; i != -1; i = nex[i])
        {
            int v = Node[i].v;
            if(d[v] == d[u] + 1 && Node[i].c > 0)
            {
                int V = dfs(v, min(cap, Node[i].c));
                Node[i].c -= V;
                Node[i ^ 1].c += V;
                ret += V;
                cap -= V;
                if(cap == 0) break;
            }
        }
        if(cap > 0) d[u] = -1;
        return ret;
    }
    
    int Dinic()
    {
        int ans = 0;
        while(bfs())
        {
            memcpy(cur, head, sizeof head);
            ans += dfs(s, INF);
        }
        return ans;
    }
    
    int main()
    {
        while(scanf("%d%d%d", &n, &m, &k) != EOF)
        {
            int sum = 0;
            s = 0, t = n * m + 1;
            mem(head, -1), cnt = 0, mem(vv, 0);
            int w, x, y;
            rap(i, 1, n)
                rap(j, 1, m)
                    rd(way[i][j]), sum += way[i][j];
            rap(i, 1, k)
            {
                rd(x), rd(y);
                if((x + y) & 1)
                    add(s, (x - 1) * m + y, INF);
                else add((x - 1) * m + y, t, INF);
                vv[x][y] = 1;
            }
            rap(i, 1, n)
                rap(j, 1, m)
                {
                    rep(k, 0, 4)
                    {
                        int nx = i + dir[k][0];
                        int ny = j + dir[k][1];
                        if(nx < 1 || ny < 1 || nx > n || ny > m) continue;
                        if((i + j) & 1)
                            add((i - 1) * m + j, (nx - 1) * m + ny, 2 * (way[i][j] & way[nx][ny]));
                    }
                    if(vv[i][j]) continue;
                    if((i + j) & 1) add(s, (i - 1) * m + j, way[i][j]);
                    else add((i - 1) * m + j, t, way[i][j]);
                }
            cout << sum - Dinic() << endl;
    
        }
    
    
    
        return 0;
    }
      
     

    Game

    Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 1563    Accepted Submission(s): 664


    Problem Description
    onmylove has invented a game on n × m grids. There is one positive integer on each grid. Now you can take the numbers from the grids to make your final score as high as possible. The way to get score is like
    the following:
    ● At the beginning, the score is 0;
    ● If you take a number which equals to x, the score increase x;
    ● If there appears two neighboring empty grids after you taken the number, then the score should be decreased by 2(x&y). Here x and y are the values used to existed on these two grids. Please pay attention that "neighboring grids" means there exits and only exits one common border between these two grids.

    Since onmylove thinks this problem is too easy, he adds one more rule:
    ● Before you start the game, you are given some positions and the numbers on these positions must be taken away.
    Can you help onmylove to calculate: what's the highest score onmylove can get in the game?
     
    Input
    Multiple input cases. For each case, there are three integers n, m, k in a line.
    n and m describing the size of the grids is n ×m. k means there are k positions of which you must take their numbers. Then following n lines, each contains m numbers, representing the numbers on the n×m grids.Then k lines follow. Each line contains two integers, representing the row and column of one position
    and you must take the number on this position. Also, the rows and columns are counted start from 1.
    Limits: 1 ≤ n, m ≤ 50, 0 ≤ k ≤ n × m, the integer in every gird is not more than 1000.
     
    Output
    For each test case, output the highest score on one line.
     
    Sample Input
    2 2 1 2 2 2 2 1 1 2 2 1 2 7 4 1 1 1
     
    Sample Output
    4 9
    Hint
    As to the second case in Sample Input, onmylove gan get the highest score when calulating like this: 2 + 7 + 4 - 2 × (2&4) - 2 × (2&7) = 13 - 2 × 0 - 2 × 2 = 9.
     
    Author
    onmylove
     
    Source
     
    自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。
  • 相关阅读:
    字符串翻转
    windows套接字相关函数
    Windows多线程同步系列之一-----互斥对象
    Dos命令---ipconfig
    windows多线程没那么难
    CreateThread简单那多线程编程
    TCP/IP协议详解概述
    正则表达式小试牛刀--匹配我的csdn博文标题
    wireshark----教你如何抓包
    HDU1385 (Floyd记录路径)
  • 原文地址:https://www.cnblogs.com/WTSRUVF/p/9976116.html
Copyright © 2011-2022 走看看