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
",ans);
}

这里写图片描述

原文地址:https://www.cnblogs.com/SiriusRen/p/6532233.html