• 【网络流24题----04】魔术球问题


    问题描述: 
    假设有n根柱子,现要按下述规则在这n根柱子中依次放入编号为 1,2,3,4......的球。 
    (1)每次只能在某根柱子的最上面放球。 
    (2)在同一根柱子中,任何2个相邻球的编号之和为完全平方数。 
    试设计一个算法,计算出在n根柱子上最多能放多少个球。例如,在4 根柱子上最多可
    放11个球。 
    ´编程任务: 
    对于给定的n,计算在 n根柱子上最多能放多少个球。

    ´数据输入: 
    文件第1 行有 1个正整数n,表示柱子数。 
    ´结果输出: 
    文件的第一行是球数。

    数据规模

    n<=60  保证答案小于1600

    输入文件示例

    4

    输出文件示例

    11

    方案如下

    1 8 
    2 7 9 
    3 6 10 
    4 5 11

    每一行表示一个柱子上的球


    如果不要输出方案好题立马变水题(可以用式子直接输出答案)

    假设我不知道式子:问题变成最小路径覆盖,并且路径不能相交,如果一个数加上一个比他大的数是完全平方数,直接连有向边即可。

     枚举答案,每次往如图中放入一个点,然后再残量网络上继续更新答案,判断所需路径数是否>n即可。


     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<vector>
     5 #include<cstdlib>
     6 #include<cmath>
     7 #include<cstring>
     8 using namespace std;
     9 #define maxn 5000
    10 #define llg int
    11 #define inf (llg)1e16 
    12 #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
    13 llg m,r[maxn],c[maxn],tot,k,N=4999;
    14 
    15 struct DINIC
    16 {
    17     vector<llg>a[maxn],ba[maxn],val[maxn];
    18     llg dl[maxn],deep[maxn],bj[maxn];
    19 
    20     void insert(llg x,llg y,llg z)
    21     {
    22         a[x].push_back(y),val[x].push_back(z);
    23         a[y].push_back(x),val[y].push_back(0);
    24         ba[x].push_back(a[y].size()-1); ba[y].push_back(a[x].size()-1);
    25     }
    26 
    27     void in(llg x)
    28     {
    29         for (llg i=1;i<x;i++) 
    30             if (floor(sqrt(i+x))*floor(sqrt(i+x))==x+i)
    31 
    32             {
    33                 insert(i*2,x*2-1,1);
    34             }
    35         insert(0,x*2,1);
    36         insert(x*2-1,N,1);
    37     }
    38 
    39     llg dfs(llg x,llg low)
    40     {
    41         llg va=0,inc=0;
    42         if (x==N) return low;
    43         llg w=a[x].size();
    44         for (llg i=0;i<w;i++)
    45             if (deep[x]+1==deep[a[x][i]] && val[x][i]>0 && (va=dfs(a[x][i],min(low,val[x][i]))))
    46             {
    47                 val[x][i]-=va; val[a[x][i]][ba[x][i]]+=va; inc+=va;
    48                 return va;
    49             }
    50             if (!inc) deep[x]=-1;
    51         return 0;
    52     }
    53 
    54     void fencen()
    55     {
    56         llg x,w,v; deep[0]=0;
    57         memset(bj,0,sizeof(bj));
    58         llg head=0,tail=1; dl[1]=0; bj[0]=1;
    59         do
    60         {
    61             x=dl[++head]; w=a[x].size();
    62             for (llg i=0;i<w;i++)
    63             {
    64                 v=a[x][i];
    65                 if (bj[v] || val[x][i]<=0) continue;
    66                 dl[++tail]=v;
    67                 deep[v]=deep[x]+1; bj[v]=1;
    68             }
    69         }while (head!=tail);
    70     }
    71 
    72     llg dinic()
    73     {
    74         llg ans=0;
    75         while (1)
    76         {
    77             fencen();
    78             if (!bj[N]) break;
    79             ans+=dfs(0,inf);
    80         }
    81         return ans;
    82     }
    83 }G;
    84 
    85 
    86 int main()
    87 {
    88     yyj("balla");
    89     llg up; cin>>up;
    90     for (llg i=1;;i++)
    91     {
    92         G.in(i);
    93         tot+=G.dinic();
    94         if (i-tot>up){cout<<i-1; return 0;}    
    95     }
    96     return 0;
    97 }
    本文作者:xrdog 作者博客:http://www.cnblogs.com/Dragon-Light/ 转载请注明出处,侵权必究,保留最终解释权!
  • 相关阅读:
    景深概念与计算
    机器视觉相关术语
    Inno Setup 怎么编译文件的版本号
    Qt 可执行程序写入版本信息
    Qt 程序默认管理员权限运行
    Inno Setup 改变默认路径
    Inno Setup 打包安装程序中让“是否创建快捷方式”默认为“打钩”的方法
    Inno Setup 如何让生成的setup.exe文件双击以管理员权限打开
    Inno Setup 打包出的安装程序以管理员身份运行
    InnoSetup 安装前卸载旧版程序
  • 原文地址:https://www.cnblogs.com/Dragon-Light/p/6357776.html
Copyright © 2020-2023  润新知