1004. To Buy or Not to Buy - Hard Version (35)

来源:互联网 发布:mac 安装软件如何卸载 编辑:程序博客网 时间:2024/05/13 09:22

本题是PAT上的一道题目。采用的是深度优先的暴力法,并适当剪枝,目前没有找到更好的方法。将每一个bread string,用一个向量vector表示:[a0,a1,a2,…,an-3,an-2,an-1]。其中a0-an-3是Eva needed colors,an-2是extra,an-1是miss。
剪枝思路:
对于不包含Eva想要的color的bread string是无用的,直接去掉,不予考虑。
如果当前已经满足了Eva全部想要的color,以满足,该条分枝不需要继续搜素下去;并且如果extra为0,那么已经是最佳结果了,结束。
如果剩下的所有未考虑的串已经无法满足了,不再继续深度优先搜索。

代码如下:

#include<vector>#include<iostream>#include<string>#include<map>using namespace std;void vecMinus(vector<int> num1,vector<int> num2,vector<int> &ans)/*num1-num2,注意extra和miss部分的计算*/{    int n = num1.size();    int miss=0,extra=0;    for(int i=0;i<=n-3;++i)    {        int t = num1[i]-num2[i];        if(t<=0){            extra +=-t;            t=0;        }        else        {            miss+=t;        }        ans.push_back(t);    }    ans.push_back(extra+num1[n-2]+num2[n-2]);    ans.push_back(miss);}void deepFFunc(vector<int> wants,int t,vector<vector<int>> &strings,vector<int> &totals,int &extra,int &miss)/*wants 是搜索到当前t位置,Eva还没有被满足的need colors;t是搜索到的位置,strings是提供的所有有用的bread string;total是所有未被搜索到(t之后)的strings的和;*/{    if(extra==0) return;//已经找到了最合适的    int n = wants.size();    int textra = wants[n-2];    int tmiss = wants.back();    if(t>=strings.size())    {        if(tmiss<miss) miss = tmiss;        if(tmiss==0&&textra <extra){            extra = textra;            //miss = 0;        }        return;    }    if(tmiss==0)//搜索到t之前,已经满足Eva需求    {        if(textra<extra) extra = textra;        //miss = tmiss;        return;    }    vector<int> ttmp;    vecMinus(wants,totals,ttmp);    if(ttmp.back()>0){//剩下的串无法满足,不需要继续搜素        if(miss>ttmp.back()) miss = ttmp.back();        return;    }    vector<int> tmp;    vecMinus(wants,strings[t],tmp);    ttmp.clear();    vecMinus(totals,strings[t],ttmp);//此处ttmp是t之后的串的和    deepFFunc(tmp,t+1,strings,ttmp,extra,miss);//买第t串    deepFFunc(wants,t+1,strings,ttmp,extra,miss);//不买第t串}int main(){    string want_str;    cin>>want_str;    int n;    cin>>n;    vector<int> wants;    int char_n=-1;    map<char,int> charToId;    int want_n=0;    for(int i=0;i<want_str.size();++i)    {        map<char,int> ::iterator it = charToId.find(want_str[i]);        if(it==charToId.end()){            charToId[want_str[i]]=++char_n;            wants.push_back(1);        }else            wants[it->second]++;        want_n++;    }    wants.push_back(0);//初始化Eva的need colors,miss是各color的和,extra为0;    wants.push_back(want_n);    vector<vector<int>> strings;    vector<int> totals(wants.size(),0);    for(int i=0;i<n;++i)    {        string str_tmp;        cin>>str_tmp;        vector<int> string_tmp(wants.size());        bool flag = false;//该串是否有用        for(int j=0;j<str_tmp.size();++j)        {            map<char,int> ::iterator it = charToId.find(str_tmp[j]);            if(it==charToId.end()){                string_tmp[wants.size()-2]++;            }            else            {                flag = true;                string_tmp[it->second]++;                totals[it->second]++;            }        }        if(flag) strings.push_back(string_tmp);    }    int extra = 0x7fffffff,miss=0x7fffffff;    deepFFunc(wants,0,strings,totals,extra,miss);    if(extra!=0x7fffffff)    {        cout<<"Yes "<<extra<<endl;    }    else        cout<<"No "<<miss<<endl;    return 0;}

可能是剪枝还算比较多,各case的最后运行时间小于10ms。

0 0
原创粉丝点击