Description
假设有n根柱子,现要按下述规则在这n根柱子中依次放入编号为1,2,3,...的球。 (1)每次只能在某根柱子的最上面放球。 (2)在同一根柱子中,任何2个相邻球的编号之和为完全平方数。 试设计一个算法,计算出在n根柱子上最多能放多少个球。例如,在4 根柱子上最多可放11 个球。 对于给定的n,计算在n根柱子上最多能放多少个球。
Input
多组数据输入. 每组输入1个正整数n,表示柱子数。
Output
每组输出n 根柱子上最多能放的球数。
Sample Input
4
Sample Output
11
Hint
Source
线性规划与网络流24题
你能不能再笨一点……→_→开始是卡在不理解为什么最小路径覆盖=顶点数-匹配数,看了那个裸的最小路径覆盖总算是明白了:
因为限制了左侧的每一个点和源点的流量都是1,就是限制了每个点只能用一次。因为每个点自身也可以算作是一个路径嘛,所以如果没有一个匹配的,那么路径数=顶点数,那么有匹配的话,路径数=顶点数-匹配数。
后来又卡在,每次加入一对点就要进行一次增广,但是黄大神的模板很明显node是连续的,你丫的是不是傻,dest设成1不就行了吗→_→输出依旧不会,遇到再说吧
/*************
nefu486
2016.1.18
1404k 260ms C++ (g++ 3.4.3)
*************/
#include<cstdio>
using namespace std;
const int mm=1111111;
const int mn=11111;
const int oo=1000000000;
int node,src,dest,edge,ret;
int reach[mm],cap[mm],flow[mm],next[mm];
int head[mn],work[mn],dis[mn],q[mn];
bool square[mn]={0};
inline int min(int a,int b)
{
return a<b?a:b;
}
inline void prepare(int _node,int _src,int _dest)
{
node=_node,src=_src,dest=_dest;
for(int i=0;i<node;++i)head[i]=-1;
edge=ret=0;
}
inline void addedge(int u,int v,int c)
{
reach[edge]=v,cap[edge]=c,flow[edge]=0,next[edge]=head[u],head[u]=edge++;
reach[edge]=u,cap[edge]=0,flow[edge]=0,next[edge]=head[v],head[v]=edge++;
}
bool Dinic_bfs()
{
int i,u,v,l,r=0;
for(i=0;i<node;++i)dis[i]=-1;
dis[q[r++]=src]=0;
for(l=0;l<r;++l)
for(i=head[u=q[l]];i>=0;i=next[i])
if(flow[i]<cap[i]&&dis[v=reach[i]]<0)
{
dis[q[r++]=v]=dis[u]+1;
if(v==dest)return 1;
}
return 0;
}
int Dinic_dfs(int u,int exp)
{
if(u==dest)return exp;
for(int &i=work[u],v,tmp;i>=0;i=next[i])
if(flow[i]<cap[i]&&dis[v=reach[i]]==dis[u]+1&&(tmp=Dinic_dfs(v,min(exp,cap[i]-flow[i])))>0)
{
flow[i]+=tmp;
flow[i^1]-=tmp;
return tmp;
}
return 0;
}
int Dinic_flow()
{
int i,delta;
while(Dinic_bfs())
{
for(i=0;i<node;++i)work[i]=head[i];
while((delta=Dinic_dfs(src,oo)))ret+=delta;
}
return ret;
}
void output(int u)
{
q[u>>1]=1;
for(int i=head[u],v;i>=0;i=next[i])
if(q[v=reach[i]>>1]==0&&flow[i]==1)printf(" %d",v),output(v<<1);
}
int main()
{
//freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
int i,n,u,v,ans;
for(i=1;i*i<mn;++i)square[i*i]=1;
while(scanf("%d",&n)!=-1)
{
ans=n;
prepare(n+n+2,0,1);
for(u=2;u<n+n+2;++u)
if(u&1)addedge(u,dest,1);
else addedge(src,u,1);
for(u=1;u<=n;++u)
for(v=u+1;v<=n;++v)
if(square[u+v])addedge(u<<1,(v<<1)+1,1);
while(ans<=Dinic_flow()+n)
{
++ans;
head[u=node++]=-1;
head[v=node++]=-1;
addedge(0,u,1);
addedge(v,1,1);
for(u=1;u<ans;++u)
if(square[u+ans])addedge(u<<1,v,1);
}
printf("%d\n",ans-1);
n=ans-1;
/* prepare(n+n+2,0,1);
for(u=2;u<n+n+2;++u)
if(u&1)addedge(u,dest,1);
else addedge(src,u,1);
for(u=1;u<=n;++u)
for(v=u+1;v<=n;++v)
if(square[u+v])addedge(u<<1,(v<<1)+1,1);
Dinic_flow();
for(u=1;u<ans;++u)q[u]=0;
for(u=1;u<ans;++u)
if(!q[u])
{
printf("%d",u);
output(u<<1);
printf("\n");
}*/
}
}