0x21 剪枝
这一章真是心态崩,剪枝太玄学啦,特别是那个搜索顺序我靠真的。。。
poj1011 枚举答案,搜索记录当前到第几根木棒。 剪枝:1、从大到小排序 2、排除等效,这个感觉还行,就是木棒按大小顺序进去,去除顺序不同的相同的情况,相同的木棒也是不用管的。 好的前面这些都可以想,关键是第三个,拼接第一个失败就全部重来。这个真是没想到
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std; int n,L,C,c[];
bool cmp(int x,int y){return x>y;}
bool v[];
bool dfs(int k,int len,int last)
{
if(k==C+)return true;
if(len==L)return dfs(k+,,); int fail=;
for(int i=last+;i<=n;i++)
{
if(v[i]==false&&len+c[i]<=L&&c[i]!=fail)
{
v[i]=true;
if(dfs(k,len+c[i],i))return true;
v[i]=false;
fail=c[i];
if(len==)return false;
}
}
return false;
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
if(n==)break; int sum=;
for(int i=;i<=n;i++)
scanf("%d",&c[i]), sum+=c[i];
sort(c+,c+n+,cmp); int mmin=;
for(int i=;i*i<=sum;i++)
if(sum%i==)
{
if(i<mmin)
{
L=i, C=sum/i;
memset(v,false,sizeof(v));
if(dfs(,,)==true)mmin=min(mmin,i);
}
if(sum/i<mmin&&i*i!=sum)
{
L=sum/i, C=i;
memset(v,false,sizeof(v));
if(dfs(,,)==true)mmin=min(mmin,sum/i);
}
}
printf("%d\n",mmin);
}
return ;
}
poj1011
poj1190 这题简直就是剪枝的代表作了。。。我可以算是想出了1.5+2??个trick,但是这题整整五个剪枝啊!!!
1、大小,看到这个我都快条件反射了,管他有的没的倒序就是没错的
2、上下界,这个我想得还要复杂一点,导致有点难算,lyd就很暴力了直接开根
3、4、对于体积和表面积,到达目标的最小花费+当前花费比限制、当前最小花费大,那么就剪掉。我纠结了一会为啥一个叫可行性剪枝一个叫最优性剪枝,是因为体积是确定的而表面积是要求的
5、最***玄学的就是这个不等式了,上面全部的体积可以表示成sigema(1~dep-1)h[i]*r[i]^2,表面积就是2*sigema(1~dep-1)h[i]*r[i], 假设当前已经的体积为V
2*sigema(1~dep-1)h[i]*r[i] = 2/r[dep]*sigema(1~dep-1)h[i]*r[i]*r[dep] >= 2/r[dep]*sigema(1~dep-1)h[i]*r[i]*r[i] = 2*(N-V)/r[dep] 这个时候又可以判表面积。。。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std; int N,m,mmin,r[],h[];
int minV[],minS[];
void dfs(int k,int V,int S)
{
if(minV[k]+V>N)return ;
if(minS[k]+S>mmin)return ;
if(*(N-V)/r[k+]+S>mmin)return ;
if(k==)
{
if(minV[k]+V==N)mmin=min(mmin,S);
return ;
} int Rli=min( int(sqrt(double(N-V+))) , r[k+]- );
for(int R=Rli;R>=k;R--)
{
int Hli=min( (N-V)/(R*R) , h[k+]- );
for(int H=Hli;H>=k;H--)
{
r[k]=R;h[k]=H;
dfs(k-,V+R*R*H,S+*R*H+((k==m)?R*R:));
}
}
}
int main()
{
scanf("%d%d",&N,&m);
for(int i=;i<=m;i++)
minV[i]=i*i*i+minV[i-], minS[i]=*i*i+minS[i-]; mmin=;
r[m+]=h[m+]=;
dfs(m,,);
printf("%d\n",mmin);
return ;
}
poj1190
poj3076 状压,判点,判字母,绝望,留坟
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<bitset>
using namespace std; int cnt;
char ss[][],sc[][][];
bitset<>mp[][],tt[][][],ts[][][];
void init()
{
memset(mp,,sizeof(mp));
for(int j=;j<=;j++)//行
{
int zt=;
for(int i=;i<=;i++)
if(ss[i][j]!='-')
zt|=(<<(ss[i][j]-'A'));
for(int i=;i<=;i++) mp[i][j]|=zt;
}
for(int i=;i<=;i++)//列
{
int zt=;
for(int j=;j<=;j++)
if(ss[i][j]!='-')
zt|=(<<(ss[i][j]-'A'));
for(int j=;j<=;j++) mp[i][j]|=zt;
}
for(int i=;i<=;i+=)
for(int j=;j<=;j+=)
{
int zt=;
for(int k=;k<=;k++)
for(int l=;l<=;l++)
if(ss[i+k-][j+l-]!='-')
zt|=(<<(ss[i+k-][j+l-]-'A'));
for(int k=;k<=;k++)
for(int l=;l<=;l++)
mp[i+k-][j+l-]|=zt;
} cnt=;
for(int i=;i<=;i++)
for(int j=;j<=;j++)
{
if(ss[i][j]=='-')cnt++;
mp[i][j].flip();
}
} bitset<>p;bool v[];
bool check()
{
for(int i=;i<=;i++)
for(int j=;j<=;j++)
if(mp[i][j]==&&ss[i][j]=='-')return false; for(int i=;i<=;i++)
{
p.reset();memset(v,false,sizeof(v));
for(int j=;j<=;j++)
{
if(ss[i][j]!='-')v[ss[i][j]-'A']=true;
else p|=mp[i][j];
}
for(int o=;o<=;o++)
if(p[o]==&&v[o]==false)return false;
}
for(int j=;j<=;j++)
{
p.reset();
for(int i=;i<=;i++)
{
if(ss[i][j]!='-')v[ss[i][j]-'A']=true;
else p|=mp[i][j];
}
for(int o=;o<=;o++)
if(p[o]==&&v[o]==false)return false;
}
for(int i=;i<=;i+=)
for(int j=;j<=;j+=)
{
p.reset();memset(v,false,sizeof(v));
for(int k=;k<=;k++)
for(int l=;l<=;l++)
{
if(ss[i+k-][j+l-]!='-')v[ss[i+k-][j+l-]-'A']=true;
else p|=mp[i+k-][j+l-];
}
for(int o=;o<=;o++)
if(p[o]==&&v[o]==false)return false;
}
return true;
}
void influence(int x,int y)
{
int o=ss[x][y]-'A';
for(int j=;j<=;j++)mp[x][j][o]=;
for(int i=;i<=;i++)mp[i][y][o]=; int i=((x-)/)*+,j=((y-)/)*+;
for(int k=;k<=;k++)
for(int l=;l<=;l++)
mp[i+k-][j+l-][o]=;
}
bool bk;
void dfs(int k,int dep)
{
if(bk==true)return ; memcpy(ts[dep],mp,sizeof(ts[dep]));
memcpy(sc[dep],ss,sizeof(sc[dep]));
bool qwq=true;
while(qwq)
{
qwq=false;
for(int i=;i<=;i++)
for(int j=;j<=;j++)
{
if(ss[i][j]=='-'&&mp[i][j].count()==)
{
k--;qwq=true;
for(int o=;o<=;o++)
if(mp[i][j][o]==)
{
ss[i][j]='A'+o;
influence(i,j);
break;
}
}
}
for(int o=;o<=;o++)
{
for(int i=;i<=;i++)
{
int u=,jj;
for(int j=;j<=;j++)
if(mp[i][j][o]==)
{
u++;jj=j;
if(u==)break;
}
if(u==)
{
ss[i][jj]='A'+o;
influence(i,jj);
}
}
for(int j=;j<=;j++)
{
int u=,ii;
for(int i=;i<=;i++)
if(mp[i][j][o]==)
{
u++;ii=i;
if(u==)break;
}
if(u==)
{
ss[ii][j]='A'+o;
influence(ii,j);
}
}
for(int i=;i<=;i+=)
for(int j=;j<=;j+=)
{
int u=,ii,jj;
for(int k=;k<=;k++)
for(int l=;l<=;l++)
{
if(mp[i+k-][j+l-][o]==)
{
u++;ii=i;jj=j;
if(u==)break;
}
}
if(u==)
{
ss[ii][jj]='A'+o;
influence(ii,jj);
}
}
}
}//必定赋值
if(!check())
{
memcpy(mp,ts[dep],sizeof(mp));
memcpy(ss,sc[dep],sizeof(ss));
return ;
} if(k==)
{
bk=true;
for(int i=;i<=;i++)
{
for(int j=;j<=;j++)printf("%c",ss[i][j]);
printf("\n");
}
return ;
} int cc=,nx,ny;
for(int i=;i<=;i++)
for(int j=;j<=;j++)
if(ss[i][j]=='-'&&mp[i][j].count()<cc)
{
cc=mp[i][j].count();
nx=i,ny=j;
}
for(int o=;o<=;o++)
if(mp[nx][ny][o]==)
{
memcpy(tt[dep],mp,sizeof(tt[dep]));
ss[nx][ny]='A'+o; influence(nx,ny);
if(check())
dfs(k-,dep+); ss[nx][ny]='-';
memcpy(mp,tt[dep],sizeof(mp));
} memcpy(mp,ts[dep],sizeof(mp));
memcpy(ss,sc[dep],sizeof(ss));
}
int main()
{
for(int i=;i<=;i++)scanf("%s",ss[i]+);
init(); bk=false;dfs(cnt,);
return ;
}
poj3076(TLE)
0x21 剪枝的更多相关文章
- α-β剪枝算法的java语言实现(非常实用)
利用α-β剪枝算法,对下图所示的博弈树进行搜索,搜索得到根节点选择的走步,以及没有必要进行评估的节点,并求出给出在何处发生了剪枝,以及剪枝的类型(属于α剪枝还是β剪枝). 注:□表示MIN节点:○表示 ...
- Sicily 1153: 马的周游问题(DFS+剪枝)
这道题没有找到一条回路,所以不能跟1152一样用数组储存后输出.我采用的方法是DFS加剪枝,直接DFS搜索会超时,优化的方法是在搜索是优先走出度小的路径,比如move1和move2都可以走,但是如走了 ...
- HDU5887 Herbs Gathering(2016青岛网络赛 搜索 剪枝)
背包问题,由于数据大不容易dp,改为剪枝,先按性价比排序,若剩下的背包空间都以最高性价比选时不会比已找到的最优解更好时则剪枝,即 if(val + (LD)pk[d].val / (LD)pk[d]. ...
- HDU5937 Equation(DFS + 剪枝)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5937 Description Little Ruins is a studious boy, ...
- alpha-beta剪枝搜索
•一种基于剪枝( α-βcut-off)的深度优先搜索(depth-first search). •将走棋方定为MAX方,因为它选择着法时总是对其子节点的评估值取极大值,即选择对自己最为有利的着法: ...
- POJ1190生日蛋糕[DFS 剪枝]
生日蛋糕 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 18236 Accepted: 6497 Description ...
- *HDU1455 DFS剪枝
Sticks Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Subm ...
- HDU1010 DFS+剪枝
Tempter of the Bone Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Othe ...
- HDU 5113 dfs剪枝
题意:告诉格子规格,颜色个数,以及每个颜色能涂得格子数目,问是否能够实现相邻两个格子的颜色数目不相同. 分析:因为数据很小,格子最多是5 * 5大小的,因此可以dfs.TLE了一次之后开始剪枝,31m ...
随机推荐
- flex和layout移动端布局
1.九宫格 样式为: ul{ display: flex; flex-wrap: wrap;//超出换行 } li{ width: 33%; height: 60px; display: flex; ...
- A - Dubstep
Problem description Vasya works as a DJ in the best Berland nightclub, and he often uses dubstep mus ...
- Kettle 版本及使用问题
kettle 简介 Kettle也叫PDI (Pentaho Data Intergration) Kettle 版本及下载 7.1及更早版本: https://sourceforge.net/pro ...
- zabbix监控超详细搭建过程(转)
监控及zabbix 目录: 1 监控分类... 1 1.1 硬件监控... 1 1.2 系统监控... 2 1.3 网络监控... 3 1.4 ...
- C语言基础 (10) 变量作用域,生命周期 内存结构
01 课程回顾 1.指针数组 注意: 对于数组来说,在使用sizeof的时候a和&a[0]是不一样的, 虽然以%x打印出来他们都是地址 2.值传递 int a; fun(a); int *** ...
- Bash中文速查表
最好用的中文速查表(Cheatsheet) 来源:https://github.com/skywind3000/awesome-cheatsheets 感谢网友们的贡献! ############## ...
- 多行文本省略号样式失效丢失,以及控制台显示autoprefixer警告'Autoprefixer applies control comment to whole block, not to next rules.'
问题现象 使用webpack压缩打包vue项目,遇到一个问题,文本多行显示省略号的关键css语句-webkit-box-orient: vertical;莫名其妙丢失失效了.查阅资料,有不少人提出 ...
- django rest-farme-work 的使用(1)
Django REST框架是一个用于构建Web API的强大且灵活的工具包 您可能想要使用REST框架的一些原因: 可浏览性 身份认证 支持ORM和非ORM的序列化 良好的文档支持 安装初步 pip ...
- mybatis 批量导入数据到mysql返回批量Id
1.首先mybatis版本必需是3.3.1或以上 2.mapper配置文件中 <insert id="insertOrderBatch" parameterType=&quo ...
- Centos6.5安装Seafile,遇到的问题处理记录。
问题1:启动Seafile安装脚本时,提示找不到MySQL-python模块,使用yum安装成功也提示未安装该软件包 问题1解决方法:需要通过 python 的工具pip来安装MySQL-python ...