題意:給出一個序列找滿足條件的子序列:非遞減+長度+位置
兩個重判:如果當(dāng)前搜索元素是子序列的第一個元素時,從原始序列的初始位置開始到當(dāng)前位置,如果當(dāng)前元素已經(jīng)出現(xiàn)過了,就不在搜索此元素了(肯定被搜索過了)
:如果當(dāng)前搜索元素不是子序列的第一個元素時,找到子序列中前一個元素對應(yīng)原始序列的位置,從該位置的下一個到當(dāng)前元素的位置,如果當(dāng)前元素已經(jīng)出現(xiàn)過了,就不在搜索此元素了(肯定被搜索過了)。
剪枝:如果搜索到長度len沒有一個滿足條件的解,那么大于此長度的也肯定不滿足,故應(yīng)減掉。
#include<cstdio>#include<cstring>using namespace std;const int maxn=1000+10;int order[maxn]; //存儲輸入序列 struct node{ int pos,t; //當(dāng)前數(shù)字t對應(yīng)序列order中的位置pos }nt[maxn]; int n,p;int len,count1; //當(dāng)前長度和輸出的序列個數(shù) bool flag; // 剪枝判斷(若當(dāng)前長度len沒有一個滿足解的,那么>len的肯定不滿足了,故減掉) void PRint(){ for(int i=0;i<len-1;i++)printf("%d ",nt[i].t); printf("%d/n",nt[len-1].t); }bool check(int p1,int p2){ for(int i=p1;i<p2;i++){ if(order[i]==order[p2])return false; } return true;}void dfs(int deepth,int pos){ //當(dāng)前子序列中的元素個數(shù)deepth,及在order序列中的位置 if(count1>=p)return ; if(deepth==len){ print(); count1++; flag=false; return ; } for(int i=pos;i<n;i++){ if(deepth==0 &&!check(0,i))continue; //如果是當(dāng)前元素都是子序列的第一個 if(deepth>0 && (!check(nt[deepth-1].pos+1,i) || nt[deepth-1].t>order[i]))continue; //要滿足非遞減 nt[deepth].pos=i; nt[deepth].t=order[i]; 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]); count1=0; ok=false; for(int i=0;i<n;i++){ len=i+1; flag=true; dfs(0,0); if(flag)break; //剪枝 } printf("/n"); } return 0;}
新聞熱點
疑難解答