您的位置:首页 > 其它

POJ1010-搜索题基础

2012-07-16 21:57 369 查看
/*
虽然也认同这题是基础的搜索题,但因做题太不熟练,写了好久~
*/
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int N=4;
const int NN=1000;

int n,types,sum,maxz,a[NN],hash[NN],p
,s
;
bool tie;
void reanswer(int cnt,int _types){    //更新最优解
    types=_types; sum=cnt; maxz=a[p[cnt-1]];
    memcpy(s,p,sizeof(s));
    tie=false;
}
void judge(int cnt,int _types){
    if (_types>types) reanswer(cnt,_types);   //按邮票种类
    else if (_types==types){
        if (cnt<sum) reanswer(cnt,_types);      //按邮票数
        else if (cnt==sum && a[p[cnt-1]]>maxz) reanswer(cnt,_types); //按邮票最大面值
        else if (cnt==sum && a[p[cnt-1]]==maxz) tie=true;  //这里写错了,debug了不少时间
    }
}
void init(){
    types=-1; sum=0; maxz=0; tie=false;
}
void dfs(int x,int k,int cnt,int _types){
    if (x==0) { judge(cnt,_types); return; }
    if (cnt==N || k==n || x>(N-cnt)*a[n-1]) return; //剪枝(1.数量已达4;2.邮票种类枚举完了;3.当前邮票组合过小,已明显不能组合成功)
    int y=x;
    for (int i=cnt; i<N && x>=a[k]; i++){ //枚举当前邮票的数量从1开始
        x-=a[k];
        p[i]=k;
        dfs(x,k+1,i+1,_types+1);
    }
    dfs(y,k+1,cnt,_types);  //当前邮票不用时
}
int main(){
    int i,x;
    while (!feof(stdin)){
        memset(hash,0,sizeof(hash));
        for (i=n=0;;i++,n++){
            scanf("%d",&a[i]);
            if (a[i]==0) break;
            if (++hash[a[i]]>5) i--,n--; //去重,同面额的邮票保留最多5种即可
        }
        sort(a,a+n);  //排序,一为之后的输出有序,二使得dfs能优先搜索到有效组合
        while (scanf("%d",&x),x){
            init();
            dfs(x,0,0,0);
            printf("%d ",x);
            if (types==-1) printf("---- none\n"); //没有可用组合
            else{
                printf("(%d):",types);
                if (tie) printf(" tie");
                else for (int i=0; i<sum; i++) printf(" %d",a[s[i]]);
                printf("\n");
            }
        }
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: