由于被状压DP打自闭,觉着来dfs找找自信,没成想依旧自闭orz
给出n个数字,让你求出非递减序列,且个数
dfs(last , now , len ),main函数遍历序列长度len。
dfs思想就是深搜搜到底(当前长度now = len),然后输出,接着回溯查找下一个。这样是满足题目要求的按下标排序,下标小的在前。开个数组s[ ]保存一路过来的结果。 难点在于剪枝,这里有三种剪枝
1) 当找到的序列个数 cnt == p , 结束递归
2)例如 1 2 3 3 4 3 , 我们希望找长度为2的序列,当我们找到第一位上的值 3 即序列为 3 X , X的可选值有 3 4 3,那么最后一个3 和第一个3 是一种情况,我们要剪掉 即查找 [last+1 --- j-1] 上有没有和 a[j]相等的 , a[j] 就是最后一个3
3)假如扫了一遍过去,cnt的值没有变化,那么证明这个序列已经不存在更长的非递减子序列了,那么main直接退出
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
最近深搜写的乱七八糟,但是都莫名其妙能过hhhhh,这篇完结,接着回去刷状压DP
感觉这个代码写得还阔以
#include
#include
#include
#include
#include
#include
using namespace std;
const int maxn = 10;
const int inf = 0x3f3f3f3f;
char mp[maxn][maxn];
struct Node
{
int z,x,y;
};
vectorans;
int all;
int flag = 0;
int dir[4][2] = {-1,0,0,-1,0,1,1,0};
void dfs1(int now);
void dfs(int x,int y,int z, int now, int step)
{
mp[x][y] = 'X';
int nx = x+dir[z][0], ny = y+dir[z][1];
while(mp[nx][ny] == 'X' && nx>=1&& nx<=7 && ny>=1 && ny<=8)
{
nx = nx + dir[z][0];
ny = ny + dir[z][1];
}
if(mp[nx][ny] == 'O')
{
mp[nx-dir[z][0]][ny-dir[z][1]] = 'O';
dfs(nx,ny,z,now,step+1);
mp[nx-dir[z][0]][ny-dir[z][1]] = 'X';
mp[x][y] = 'O';
}
else
{
if(step == 0)
{
mp[x][y] = 'O';
return;
}
dfs1(now+1);
mp[x][y] = 'O';
}
}
int check()
{
int cnt = 0;
for(int i=1; i<=7; i++)
{
for(int j=1; j<=8; j++)
{
if(mp[i][j] == 'O')
{
cnt++;
if(cnt == 2)
return 0;
}
}
}
return 1;
}
void dfs1(int now) // 开始拉一下
{
if(check())
{
for(int t=0; t=1&& nx<=7 && ny>=1 && ny<=8)
{
//ans[now] = make_pair(z,make_pair(i,j));
Node p;
p.z = z;
p.x = i;
p.y = j;
ans.push_back(p);
dfs(i,j,z,now+1,0);
ans.pop_back();
if(flag == 1)
return;
}
}
}
}
}
}
int main()
{ int cas = 1;
while(scanf("%s",mp[1]+1) != EOF)
{
flag = 0;
for(int i=2; i<=7; i++)
scanf("%s",mp[i]+1);
for(int i=1; i<=7; i++)
{
for(int j=1; j<=8; j++)
if(mp[i][j] == 'O')
{
all++;
}
}
if(cas != 1)
cout<