洛谷 [P2765] 魔术球问题
贪心做法
每次尽可能选择已经放过球的柱子
#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] 魔术球问题的更多相关文章
- 洛谷 P2765 魔术球问题 解题报告
P2765 魔术球问题 题目描述 问题描述: 假设有\(n\)根柱子,现要按下述规则在这\(n\)根柱子中依次放入编号为\(1,2,3,\dots\)的球. \((1)\) 每次只能在某根柱子的最上面 ...
- 洛谷 P2765 魔术球问题 (dinic求最大流,最小边覆盖)
P2765 魔术球问题 题目描述 «问题描述: 假设有n根柱子,现要按下述规则在这n根柱子中依次放入编号为1,2,3,...的球. (1)每次只能在某根柱子的最上面放球. (2)在同一根柱子中,任何2 ...
- 洛谷P2765魔术球问题 最小路径覆盖
https://www.luogu.org/problemnew/show/P2765 看到这一题第一眼想到:这不是二分最大流吗,后来发现还有一种更快的方法. 首先如果知道要放多少个球求最少的柱子,很 ...
- 洛谷P2765 魔术球问题(最大流)
传送门 %%%KSkun大佬 话说明明是网络流……这题竟然还有打表找规律和纯贪心AC的……都是神犇啊…… 来说一下如何建图.首先把每一个点拆成$X_i$和$Y_i$,然后$S$向$X_i$连一条容量为 ...
- 洛谷P2765 魔术球问题(贪心 最大流)
题意 已经很简洁了吧. 假设有n根柱子,现要按下述规则在这n根柱子中依次放入编号为1,2,3,...的球. (1)每次只能在某根柱子的最上面放球. (2)在同一根柱子中,任何2个相邻球的编号之和为完全 ...
- 洛谷P2765 魔术球问题
题目链接:https://www.luogu.org/problemnew/show/P2765 知识点: 最大流 解题思路: 本题所有边的容量均为 \(1\). 从 \(1\) 开始加入数字,将这个 ...
- P2765 魔术球问题
P2765 魔术球问题 贪心模拟就可以过.........好像和dinic没啥关系 找找规律发现可以贪心放.n又灰常小. 设答案=m 你可以$O(mn)$直接模拟过去 闲的慌得话可以像我用个$se ...
- P2765 魔术球问题 网络流二十四题重温
P2765 魔术球问题 知识点::最小点覆盖 这个题目要拆点,这个不是因为每一个球只能用一次,而是因为我们要求最小点覆盖,所以要拆点来写. 思路: 首先拆点,然后就是开始建边,因为建边的条件是要求他们 ...
- [洛谷P2113] 看球泡妹子
洛谷题目链接:看球泡妹子 题目背景 2014年巴西世界杯开幕了,现在满城皆是世界杯,商家们利用它大赚一笔,小明和小红也借此机会增进感情. 题目描述 本届世界杯共有N支球队,M场比赛.男球迷小明喜欢看比 ...
随机推荐
- Kafka+Zookeeper集群搭建
上次介绍了ES集群搭建的方法,希望能帮助大家,这儿我再接着介绍kafka集群,接着上次搭建的效果. 首先我们来简单了解下什么是kafka和zookeeper? Apache kafka 是一个分布式的 ...
- Centos7安装docker-compse踩过的坑
一.概要 本文,我们介绍如何在centos7环境下安装docker-compose, 记录下安装过程步骤以及遇到的问题还有解决办法. 二.安装方式 1.官方安装方式 sudo curl -L ht ...
- 《图解http》知识点笔记
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Helvetica } p.p2 { margin: 0.0px 0.0px 0.0px 0. ...
- php artisan 命令报错,什么命令都是这个错误,cmd下运行也不行,又没看到语法错误
Laravel 5.1 以上的版本的框架需求PHP的版本是5.5以上的版本.如果你的PHP版本等级太低,将会出现上述的问题. 估计你要升级你的PHP版本了.
- putty 与winscp 区别
https://zhidao.baidu.com/question/377968180.html putty 与winscp 有什么区别, 装了 winscp 可以由 putty 替换么 ? 具体用法 ...
- VisualSFM+PMVS生成稠密点云
利用相机拍摄一个场景不同角度的图片,使用VisualSFM能够得到稀疏点云,如果想要得到稠密点云,可以在VisualSFM中加入PMVS的应用程序,PMVS会作为一个插件运行将稀疏点云插成稠密的点云. ...
- MYSQL GROUP BY Optimization
GROUP BY Optimization 常规的匹配group by(分组)操作子句是扫整表并且创建包含连续的分组行的临时表, 利用临时表得到group数据,运用appregate function ...
- Netty 拆包粘包和服务启动流程分析
Netty 拆包粘包和服务启动流程分析 通过本章学习,笔者希望你能掌握EventLoopGroup的工作流程,ServerBootstrap的启动流程,ChannelPipeline是如何操作管理Ch ...
- 一分钟搭建Vue2.0+Webpack2.0多页面项目
想要自己一步步搭建的比较麻烦,不是很推荐,最少也要使用vue-cli,在其基础上开始搭建,今天我的主题是一分钟搭建,那么常规方法肯定不能满足的, 而我用的方法也很简单,就是使用已经配置完成的demo模 ...
- Redis-配置认证密码
1.找到redis.conf,配置密码 2.要重新启动一下redis 3.用redis-cli重新登陆,我们查询的时候提示"Authentication required"查询失败 ...