POJ 1167 The Buses 暴搜+剪枝
思路:
先把能选的路线都预处理出来
按照能停的车的多少排个序 (剪枝1)
搜搜搜
如果当前剩的车÷当前能停车的多少+deep>=ans剪掉 (剪枝2)
//By SiriusRen
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n,vis[60],xx,cnt,ans=17;
struct Route{int start,gap,all;}route[1005];
bool check(int start,int gap){
for(int i=start;i<60;i+=gap)
if(!vis[i])return 0;
return 1;
}
bool cmp(Route a,Route b){return a.all>b.all;}
void dfs(int x,int deep,int remain){
if(remain/route[x].all+deep>=ans)return;
if(!remain){ans=min(ans,deep);return;}
for(int i=x;i<=cnt;i++){
if(check(route[i].start,route[i].gap)){
for(int j=route[i].start;j<60;j+=route[i].gap)
vis[j]--;
dfs(i,deep+1,remain-route[i].all);
for(int j=route[i].start;j<60;j+=route[i].gap)
vis[j]++;
}
}
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&xx),vis[xx]++;
for(int i=0;i<30;i++)
for(int j=i+1;i+j<60;j++)
if(check(i,j)){
route[++cnt].gap=j,route[cnt].start=i;
for(int k=route[cnt].start;k<60;k+=route[cnt].gap)route[cnt].all++;
}
sort(route+1,route+1+cnt,cmp);
dfs(1,0,n);
printf("%d\n",ans);
}