2610 按照長(zhǎng)度優(yōu)先 位置次之 輸出所有不遞減序列
2611 按照長(zhǎng)度優(yōu)先 大小次之 輸出所有不遞減序列,2610的加強(qiáng)版
思路:本題的重判和剪枝方法和2610的基本不變,不再累述;首先按照長(zhǎng)度輸出,然后當(dāng)長(zhǎng)度相同時(shí),按照字典序最小輸出(因此用sort對(duì)序列進(jìn)行排序)此時(shí)要特別注意,輸出的子序列元素位置對(duì)應(yīng)于原序列的位置下標(biāo)一定要保證是遞增的,所以用結(jié)構(gòu)體來(lái)存儲(chǔ)值和下標(biāo)。本題還需要注意的問(wèn)題是第二種判重(見2610題解),在判重的時(shí)候不能在排好序的數(shù)組中判重,應(yīng)該在原數(shù)組中遍歷,看是否已經(jīng)出現(xiàn)過(guò)當(dāng)前數(shù)字,因?yàn)槟阍谂藕眯虻臄?shù)組中這樣判重的話,會(huì)把一些合法的答案棄掉了(本題的關(guān)鍵)。
比如原序列1 2 3 2 3 排好序后是1 2 2 3 3,現(xiàn)在搜長(zhǎng)度為4的子串,已搜1 2 2 ,現(xiàn)在搜第四個(gè)3,發(fā)現(xiàn)第四個(gè)數(shù)3在原數(shù)組中的位置是3 < 第3個(gè)數(shù)2在原數(shù)組中的位置4,不合法,棄之,然后搜第5個(gè)3,現(xiàn)在執(zhí)行第二種判重,如果在排好序的數(shù)組中判重的話,就會(huì)發(fā)現(xiàn)第四個(gè)位置有了3,于是也會(huì)放棄這組,而實(shí)際情況是,1 2 2 3 是合法的!所以要在第三個(gè)2在原數(shù)組的位置4開始,到第五個(gè)數(shù)3在原數(shù)組的位置5之間看有沒有3出現(xiàn),顯然是沒有的,所以1 2 2 3 合法。
兩道經(jīng)典搜索題hdu2610 2611
#include<cstdio>#include<algorithm>using namespace std;const int maxn=100+10;struct node{ int t; //值 int pos; //對(duì)應(yīng)序列中的位置 }son[maxn],order[maxn]; //子序列、輸入序列 int yuan[maxn]; //原序列 int n,p;int len,count1; //當(dāng)前子序列長(zhǎng)度、輸出的子序列個(gè)數(shù) bool flag; //剪枝判斷 bool cmp(const node& n1,const node& n2){ //用于sort的排序函數(shù) if(n1.t!=n2.t) return n1.t<n2.t; return n1.pos<n2.pos; }void PRint(){ for(int i=0;i<len-1;i++)printf("%d ",son[i].t); printf("%d/n",son[len-1].t);}bool check1(int p1,int p2){ //當(dāng)前搜索元素是子序列的第一個(gè)時(shí)用check1 for(int i=p1;i<p2;i++) if(order[i].t==order[p2].t)return false; return true;} bool check2(int p1,int p2){ //前搜索元素不是子序列的第一個(gè)時(shí)用check2 for(int i=p1;i<p2;i++) if(yuan[i]==yuan[p2])return false; return true;} void dfs(int deepth,int pos){ if(count1>=p)return ; if(deepth==len){ print(); count1++; flag=false; return ; } for(int i=pos;i<n;i++){ if(deepth==0 && !check1(0,i))continue; if(deepth>=1 && (!check2(son[deepth-1].pos+1,order[i].pos) || son[deepth-1].pos>order[i].pos))continue; son[deepth].pos=order[i].pos; son[deepth].t=order[i].t; dfs(deepth+1,i+1); }} int main(){ while(scanf("%d%d",&n,&p)==2){ for(int i=0;i<n;i++){ scanf("%d",&order[i].t); order[i].pos=i; yuan[i]=order[i].t; } sort(order,order+n,cmp); count1=0; for(int i=0;i<n;i++){ len=i+1; flag=true; dfs(0,0); if(flag)break; //剪枝(列如當(dāng)len=3時(shí)無(wú)解,那么>3就肯定不滿足了) printf("/n"); } }}
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注