题目链接:codeforces 339E
解题思路:
一上来就像到了搜索,但是被数据量吓到了,不过发现搜索最多三层的时候,我就打算用剪枝来试试看了,关键在于扩展结点太多的结点需要丢掉这一点!
代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int n,a[1005],flag;
int pnum[10],qnum[10],ppos[10][1005];
int ans_num,ans[10];
struct node{
int l,r;
}qpos[10][1005];
bool is(){
for(int i=1;i<=n;i++)
if(a[i]!=i)
return 0;
return 1;
}
void find(int index)
{
pnum[index]=0;
ppos[index][++pnum[index]]=1;
for(int i=2;i<n;i++)
{
if(! (a[i-1]==a[i]-1&&a[i+1]==a[i]+1
|| a[i-1]==a[i]+1&&a[i+1]==a[i]-1))
ppos[index][++pnum[index]]=i;
}
ppos[index][++pnum[index]]=n;
}
void to_pair(int index)
{
qnum[index]=0;
for(int i=1;i<=pnum[index];i++)
{
for(int j=i;j<=pnum[index];j++)
{
qpos[index][++qnum[index]].l=ppos[index][i];
qpos[index][qnum[index]].r=ppos[index][j];
}
}
}
void dfs(int index)
{
if(flag) return;
if(index==4)
{
if(is())
flag=1;
return;
}
for(int i=1;i<=qnum[index];i++)
{
reverse(a+qpos[index][i].l, a+qpos[index][i].r+1);
find(index+1);
if(pnum[index+1]>10) // 剪枝
{
reverse(a+qpos[index][i].l, a+qpos[index][i].r+1);
continue;
}
to_pair(index+1);
ans[index*2-1]=qpos[index][i].l;
ans[index*2]=qpos[index][i].r;
dfs(index+1);
if(flag) return;
reverse(a+qpos[index][i].l, a+qpos[index][i].r+1);
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
flag=0,ans_num=3;
find(1), to_pair(1);
dfs(1);
for(int i=1;i<=3;i++)
if(ans[2*i]==ans[2*i-1])
ans_num--;
printf("%d\n",ans_num);
for(int i=3;i>=1;i--)
if(ans[2*i]!=ans[2*i-1])
printf("%d %d\n", ans[2*i-1], ans[2*i]);
return 0;
}
总结:
剪枝其实有时候是可以很随意的,不要被数据量吓倒了,大胆深搜吧!