POJ 1011的一个快速实现
2009-04-22 19:14
393 查看
http://acm.pku.edu.cn/JudgeOnline/problem?id=1011
通过剪枝和记录历史搜索数据
可以通过poj和这组变态数据
64
40 40 30 35 35
26 15 40 40 40
40 40 40 40 40
40 40 40 40 40
40 40 40 43 42
42 41 10 4 40
40 40 40 40 40
40 40 40 40 40
40 40 40 25 39
46 40 10 4 40
40 37 18 17 16
15 40 40 40 40
40 40 40 40
#include <iostream>
#include <cstdlib>
using namespace std;
int num[64];
int next[64];
int n;
bool used[64];
int len;
int searched[65][65][50*65];
int cmp(const void* a,const void* b)
{
return *((int*)b)-*((int*)a);
}
inline int sumLen(int m)
{
int sum=0;
for(int i=m; i<n; i++)
{
if(used[i]==false)
sum+=num[i];
}
return sum;
}
void Init(int total, int sum)
{
for(int i=0; i<=total; i++)
{
for(int j=0; j<=total; j++)
{
for(int k=0; k<=sum; k++)
searched[i][j][k]=0;
}
}
}
bool stick(int total, int start, int left)
{
int i;
if(total==n)
return true;
for(i=start; i<n; )
{
if(used[i]==false)
{
if(left>num[i])
{
left-=num[i];
used[i]=true;
if(searched[total+1][start+1][left]==1)
return true;
else if(searched[total+1][start+1][left]==-1)
;
else
{
if(stick(total+1,start+1,left))
{
searched[total+1][start+1][left]=1;
return true;
}
else
searched[total+1][start+1][left]=-1;
}
left+=num[i];
used[i]=false;
if(start==0)
break;
}
else if(left==num[i])
{
used[i]=true;
if(searched[total+1][0][len]==1)
return true;
else if(searched[total+1][0][len]==-1)
;
else
{
if(stick(total+1,0,len))
{
searched[total+1][0][len]=1;
return true;
}
else
searched[total+1][0][len]=-1;
}
used[i]=false;
break;
}
i=next[i];
}
else
i++;
if(sumLen(i)<left)
return false;
}
return false;
}
int main()
{
cin>>n;
int i,j;
int sum;
while(n)
{
sum=0;
for(i=0; i<n; i++)
{
cin>>num[i];
sum+=num[i];
used[i]=false;
}
qsort(num,n,sizeof(int),cmp);
int start=0;
int end=0;
while(end<n)
{
while(end<n&&num[start]==num[end])
end++;
for(j=start; j<end; j++)
{
next[j]=end;
}
start=end;
}
for(i=num[0]; i<=sum; i++)
{
// cout<<"i"<<i<<endl;
if(sum%i==0)
{
Init(n,sum);
len=i;
if(stick(0,0,len))
break;
}
}
cout<<len<<endl;
cin>>n;
}
return 0;
}
通过剪枝和记录历史搜索数据
可以通过poj和这组变态数据
64
40 40 30 35 35
26 15 40 40 40
40 40 40 40 40
40 40 40 40 40
40 40 40 43 42
42 41 10 4 40
40 40 40 40 40
40 40 40 40 40
40 40 40 25 39
46 40 10 4 40
40 37 18 17 16
15 40 40 40 40
40 40 40 40
#include <iostream>
#include <cstdlib>
using namespace std;
int num[64];
int next[64];
int n;
bool used[64];
int len;
int searched[65][65][50*65];
int cmp(const void* a,const void* b)
{
return *((int*)b)-*((int*)a);
}
inline int sumLen(int m)
{
int sum=0;
for(int i=m; i<n; i++)
{
if(used[i]==false)
sum+=num[i];
}
return sum;
}
void Init(int total, int sum)
{
for(int i=0; i<=total; i++)
{
for(int j=0; j<=total; j++)
{
for(int k=0; k<=sum; k++)
searched[i][j][k]=0;
}
}
}
bool stick(int total, int start, int left)
{
int i;
if(total==n)
return true;
for(i=start; i<n; )
{
if(used[i]==false)
{
if(left>num[i])
{
left-=num[i];
used[i]=true;
if(searched[total+1][start+1][left]==1)
return true;
else if(searched[total+1][start+1][left]==-1)
;
else
{
if(stick(total+1,start+1,left))
{
searched[total+1][start+1][left]=1;
return true;
}
else
searched[total+1][start+1][left]=-1;
}
left+=num[i];
used[i]=false;
if(start==0)
break;
}
else if(left==num[i])
{
used[i]=true;
if(searched[total+1][0][len]==1)
return true;
else if(searched[total+1][0][len]==-1)
;
else
{
if(stick(total+1,0,len))
{
searched[total+1][0][len]=1;
return true;
}
else
searched[total+1][0][len]=-1;
}
used[i]=false;
break;
}
i=next[i];
}
else
i++;
if(sumLen(i)<left)
return false;
}
return false;
}
int main()
{
cin>>n;
int i,j;
int sum;
while(n)
{
sum=0;
for(i=0; i<n; i++)
{
cin>>num[i];
sum+=num[i];
used[i]=false;
}
qsort(num,n,sizeof(int),cmp);
int start=0;
int end=0;
while(end<n)
{
while(end<n&&num[start]==num[end])
end++;
for(j=start; j<end; j++)
{
next[j]=end;
}
start=end;
}
for(i=num[0]; i<=sum; i++)
{
// cout<<"i"<<i<<endl;
if(sum%i==0)
{
Init(n,sum);
len=i;
if(stick(0,0,len))
break;
}
}
cout<<len<<endl;
cin>>n;
}
return 0;
}
相关文章推荐
- 曾经遇到的一个面试题,快速排序用链表实现,算法和以前的相似,需要注意一些细节处理
- 如何基于ARMS快速实现一个基于Nginx的网站监控场景 – 操作篇
- POJ1011 一种dfs实现
- 从无到有快速搭建一个基于Web的Mail服务器,能够实现邮件的收发
- 两个Layout一个属性快速实现Android滑动顶部悬停
- Android 快速实现一个文件选择器
- 如何快速实现一个基于 Nginx 网站的监控场景
- 100509 Ghost成为一个分区 -- 脚本实现快速定位FAT32文件系统DBR
- 一个快速实现自定义地图区域展示及导航的平台:迅达地理
- 快速实现一个简单的bigpipe模型
- 原根(详解+代码实现+例题+快速求解一个数的原根)
- 【银行管理系统】先实现一个普通窗口为普通客户服务,快速Vip类比
- 这是一个极其简便的快速实现隐藏标题栏和导航栏的库。
- 使用反射+缓存+委托,实现一个不同对象之间同名同类型属性值的快速拷贝
- poj 3070 java实现矩阵快速幂
- Objective-C ,ios,iphone开发基础:快速实现一个简单的图片查看器
- 一个自定义服务以执行脚本实现类属性的快速整齐地排列
- 快速排序的一个Java实现
- 如何快速实现一个基于 Nginx 网站的监控场景
- 实现一个快速简单的SimpleListDialog<T>