贪心做法

每次尽可能选择已经放过球的柱子

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
int num[100][1000],n;
bool chk(const int &a,const int &b){
int t=sqrt(a+b);
return t*t==a+b;
}
int main(){
cin>>n;
int cnt=0;
while(++cnt){
bool f=0;
for(int i=1;i<=n;i++){
if(num[i][0]&&chk(num[i][num[i][0]],cnt)) num[i][++num[i][0]]=cnt,f=1;
if(f) break;
}
for(int i=1;i<=n;i++){
if(!num[i][0]) num[i][++num[i][0]]=cnt,f=1;
if(f) break;
}
if(!f) break;
}
printf("%d\n",cnt-1);
for(int i=1;i<=n;i++){
for(int j=1;j<=num[i][0];j++){
printf("%d ",num[i][j]);
}
printf("\n");
}
return 0;
}

网络流做法

我们可以将其转化成最小路径覆盖问题来做,

从小到大枚举答案,对于每一个新加进去的答案,寻找在已加进去的点中,满足题意的点,连一条边.

我们发现连好以后这是一个DAG图,其最小路径覆盖就是需要的最少柱子数,我们要找到一个最小路径覆盖<=n的最大解,即最后的答案

求最小路径覆盖可以用二分图做

这里有几个优化,具体见代码

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cmath>
using namespace std;
int init(){
int rv=0,fh=1;
char c=getchar();
while(c<'0'||c>'9'){
if(c=='-') fh=-1;
c=getchar();
}
while(c>='0'&&c<='9'){
rv=(rv<<1)+(rv<<3)+c-'0';
c=getchar();
}
return fh*rv;
}
const int MAXN=5000,MAXM=50005;
int head[MAXN],n,cur[MAXN],dep[MAXN],nume,s,t,maxflow;
queue<int> q;
bool f[MAXN];
struct edge{
int to,nxt,cap,flow;
}e[MAXM<<1];
void adde(int from,int to,int cap){
e[++nume].to=to;
e[nume].nxt=head[from];
head[from]=nume;
e[nume].cap=cap;
}
bool chk(const int &a,const int &b){
int t=sqrt(a+b);
return t*t==a+b;
}
bool bfs(){
memset(dep,0,sizeof(dep));
while(!q.empty()) q.pop();
q.push(s);dep[s]=1;
while(!q.empty()){
int u=q.front();q.pop();
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
if(!dep[v]&&e[i].flow<e[i].cap){
dep[v]=dep[u]+1;
if(v==t) return 1;//搜到汇点就结束,因为最新加进来的点一定在最前面,所以,搜到的这条路径就是新加进来的路径
q.push(v);
}
}
}
return 0;
}
int dfs(int u,int flow){
if(u==t) return flow;
int tot=0;
for(int &i=cur[u];i&&tot<flow;i=e[i].nxt){
int v=e[i].to;
if(dep[v]==dep[u]+1&&e[i].flow<e[i].cap){
if(int t=dfs(v,min(flow-tot,e[i].cap-e[i].flow))){
e[i].flow+=t;
e[((i-1)^1)+1].flow-=t;
tot+=t;
}
}
}
return tot;
}
void dinic(){
while(bfs()){
for(int i=s;i<=t;i++) cur[i]=head[i];
maxflow+=dfs(s,0x3f3f3f3f);
}
}
void print(int u){
printf("%d ",u);
f[u]=1;
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to-2000;
if(!f[v]&&e[i].flow){
print(v);
return;
}
}
}
int main(){
n=init();
s=0,t=4950;
int cnt=0;
while(++cnt){
adde(s,cnt,1);adde(cnt,s,0);
adde(cnt+2000,t,1);adde(t,cnt+2000,0);
for(int i=1;i<cnt;i++){
if(chk(i,cnt)){
adde(i,cnt+2000,1);
adde(cnt+2000,i,0);
}
}
dinic();
if(cnt-maxflow>n) break;
}
printf("%d\n",cnt-1); for(int k=1;k<=n;k++){
for(int i=1;i<cnt;i++) if(!f[i]){
print(i);break;
}
printf("\n");
}
return 0;
}

洛谷 [P2765] 魔术球问题的更多相关文章

  1. 洛谷 P2765 魔术球问题 解题报告

    P2765 魔术球问题 题目描述 问题描述: 假设有\(n\)根柱子,现要按下述规则在这\(n\)根柱子中依次放入编号为\(1,2,3,\dots\)的球. \((1)\) 每次只能在某根柱子的最上面 ...

  2. 洛谷 P2765 魔术球问题 (dinic求最大流,最小边覆盖)

    P2765 魔术球问题 题目描述 «问题描述: 假设有n根柱子,现要按下述规则在这n根柱子中依次放入编号为1,2,3,...的球. (1)每次只能在某根柱子的最上面放球. (2)在同一根柱子中,任何2 ...

  3. 洛谷P2765魔术球问题 最小路径覆盖

    https://www.luogu.org/problemnew/show/P2765 看到这一题第一眼想到:这不是二分最大流吗,后来发现还有一种更快的方法. 首先如果知道要放多少个球求最少的柱子,很 ...

  4. 洛谷P2765 魔术球问题(最大流)

    传送门 %%%KSkun大佬 话说明明是网络流……这题竟然还有打表找规律和纯贪心AC的……都是神犇啊…… 来说一下如何建图.首先把每一个点拆成$X_i$和$Y_i$,然后$S$向$X_i$连一条容量为 ...

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

    题意 已经很简洁了吧. 假设有n根柱子,现要按下述规则在这n根柱子中依次放入编号为1,2,3,...的球. (1)每次只能在某根柱子的最上面放球. (2)在同一根柱子中,任何2个相邻球的编号之和为完全 ...

  6. 洛谷P2765 魔术球问题

    题目链接:https://www.luogu.org/problemnew/show/P2765 知识点: 最大流 解题思路: 本题所有边的容量均为 \(1\). 从 \(1\) 开始加入数字,将这个 ...

  7. P2765 魔术球问题

    P2765 魔术球问题 贪心模拟就可以过.........好像和dinic没啥关系   找找规律发现可以贪心放.n又灰常小. 设答案=m 你可以$O(mn)$直接模拟过去 闲的慌得话可以像我用个$se ...

  8. P2765 魔术球问题 网络流二十四题重温

    P2765 魔术球问题 知识点::最小点覆盖 这个题目要拆点,这个不是因为每一个球只能用一次,而是因为我们要求最小点覆盖,所以要拆点来写. 思路: 首先拆点,然后就是开始建边,因为建边的条件是要求他们 ...

  9. [洛谷P2113] 看球泡妹子

    洛谷题目链接:看球泡妹子 题目背景 2014年巴西世界杯开幕了,现在满城皆是世界杯,商家们利用它大赚一笔,小明和小红也借此机会增进感情. 题目描述 本届世界杯共有N支球队,M场比赛.男球迷小明喜欢看比 ...

随机推荐

  1. android下载管理、理财、浏览器、商品筛选、录音源码等

    Android精选源码 android仿美拍直播的点赞动画   android视频播放器完美切换全屏.小窗口源码   android类似随手记理财类源码   android简单浏览器源码   andr ...

  2. UEP-find查询

    实体类: @Entity @Table(name = "xxxxx") public class WzInitializeStoreInfo extends EntityBean{ ...

  3. HDU 2412 Farm Irrigation

    题目: Benny has a spacious farm land to irrigate. The farm land is a rectangle, and is divided into a ...

  4. 编写自己的JavaScript方法库

    下面列出了我在项目中经常使用到的一些方法,这些方法可以很方便的提高我们的工作效率,代码在GitHub上面,点击目录就可以跳转了,欢迎大家通过fork,改编和优化成自己的JavaScript方法库. 目 ...

  5. 本地phpstudy时常停机连接失败,php.ini文件中9000端口问题

    2018/01/05 13:35:07 [error] 20508#19380: *1 WSARecv() failed (10054: An existing connection was forc ...

  6. Laravel5中使用阿里大于(鱼)发送短信验证码

    在做用户注册和个人中心的安全管理时,我实现借助第三方短信平台(阿里大于(鱼))在Laravel框架中进行手机验证的设置:阿里大于,是阿里通信旗下优质便捷的云通信服务平台,整合了三大运营商的通信能力,为 ...

  7. 什么是WEBserver? 经常使用的WEBserver有哪些?

    地址:http://www.mamicode.com/ 什么是WEBserver? 经常使用的WEBserver有哪些? 一.什么是WEBserver Webserver能够解析HTTP协议.当Web ...

  8. 解决无限 This file is indented with tabs instead of 4 spaces

    File -> Settings -> Editor -> Code Style -> Java -> Tabs and Indents -> Use tab ch ...

  9. dedecms后台系统基本参数标题

    1,站点设置 2,核心设置 3,附件设置 4,会员设置 6,性能选项 7,其它选项 8,模块设置 在E:\wamp\www\dededln\back\inc\configgroup.txt

  10. tree conflict svn 怎么解决

    如果自己和其他人修改了同一个文件,而他已经更新到SVN,你commit时就会出现冲突,如何解决呢? 方法/步骤 使用SVN时,更新一个自己修改的文件到服务器,出现冲突,因为其他同事也修改了这个文件并且 ...