• 洛谷P2765 魔术球问题(贪心 最大流)


    题意

    已经很简洁了吧。

    假设有n根柱子,现要按下述规则在这n根柱子中依次放入编号为1,2,3,...的球。

    (1)每次只能在某根柱子的最上面放球。

    (2)在同一根柱子中,任何2个相邻球的编号之和为完全平方数。

    试设计一个算法,计算出在n根柱子上最多能放多少个球

    Sol

    这题有两种做法

    1:贪心,能放就放

    2:网络流

    首先考虑到每个元素只能用因此,拆为$a_i$,$b_i$

    从$S$向$a_i$连权值为$1$的边,从$b_i$向$T$连权值为$1$的边

    依次枚举加入的每一个数,每次跑最大流,若更优,就不断增广

    否则新开一个桶(和贪心很像

    我太菜了就写个贪心吧。。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    #include<map>
    #include<iostream>
    using namespace std;
    const int MAXN = 1e4 + 10, INF = 1e9 + 10;
    inline int read() {
        char c = getchar(); int x = 0, f = 1;
        while(c < '0' || c > '9') {if(c == '-') f = 1; c = getchar();}
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
        return x * f;
    }
    int N;
    vector<int> v[57];
    map<int, bool> mp;    
    int can(int x, int n) {
        for(int i = 1; i <= n; i++) {
            int m = v[i].size();
            if(m == 0) continue;
            if(mp[v[i][m - 1] + x] == 1) {
                v[i].push_back(x); 
                return 1;
            }
        }
        return 0;
    }
    int main() {
        for(int i = 1; i <= 10000; i++) mp[i * i] = 1;
        N = read();
        int now = 0;
        for(int i = 1; i <= N + 1; ) {
            while(can(++now, i));
            v[i++].push_back(now);
        }
        printf("%d
    ", now - 1);
        for(int i = 1; i <= N; i++, puts(""))
            for(int j = 0; j < v[i].size(); j++)
                printf("%d ", v[i][j]);
        
        return 0;
    }

  • 相关阅读:
    个人网站第一期完成
    nodebb在阿里云主机部署过程
    mongoengine教程1
    quick cocos 的scheduler 定时器
    cocos2dx调度器scheduler
    Cocos2d-x中Vector使用
    Google分布式系统三驾马车: GFS,mapreduce,Bigtable
    Linux使用记
    Eclipse快捷键总结
    详解iOS App生命周期(转)
  • 原文地址:https://www.cnblogs.com/zwfymqz/p/9353628.html
Copyright © 2020-2023  润新知