在黑书上的很好的一道搜索题,开始时基本没什么思路,代码也是按照大牛题解这里敲出来的……
#include<iostream>
using namespace std;
int bg,ed,Min,temp,sum[60],use[60],first[60];
bool yes(int s,int d)
{
int i;
for(i=s;i<60;i+=d)
if(sum[i]<=use[i])return false;
return true;
}
void mark(int s,int d,int v)
{
int i;
for(i=s;i<60;i+=d)
use[i]+=v;
}
void dfs(int u)
{
int i;
if(u==60)
{
if(temp<Min)Min=temp;
return;
}
if(temp>Min)return;
if(sum[u]<=use[u])
{
for(i=u+1;i<60;i++)
if(sum[i]>use[i])break;
dfs(i);
return;
}
for(i=bg;2*i<u;i++)
if(first[i]>0&&yes(u,u-i))
{
first[i]--;
mark(u,u-i,1);
dfs(u);
first[i]++;
mark(u,u-i,-1);
}
if(2*u<ed)
{
first[u]++;
use[u]++;
temp++;
dfs(u);
first[u]--;
use[u]--;
temp--;
}
}
int main()
{
//freopen("a.txt","r",stdin);
int i,t,n;
while(scanf("%d",&n)!=EOF)
{
memset(sum,0,sizeof(sum));
memset(use,0,sizeof(use));
for(i=0;i<n;i++)
{
scanf("%d",&t);
if(i==0)bg=t;
if(i==n-1)ed=t;
sum[t]++;
}
Min=n/2;
temp=0;
dfs(bg);
printf("%d\n",Min);
}
return 0;
}