题目:P5118 [USACO18DEC]Back and Forth
搜索 - dfs
题意过于繁琐,在这里就不做复述了
看到这题
n
=
10
n=10
n=10,就知道肯定是爆搜啦,
O
(
n
!
)
O(n!)
O(n!) 都可以过
没错这题就是爆搜,我们用 vector 分别存两个仓库里的桶,每次层 dfs 枚举用哪个桶来装牛奶,递归到边界时判断一下当前仓库
1
1
1的牛奶数量有没有出现过并打上标记,最后输出个数
#include<cstdio>
#include<iostream>
#include<vector>
using namespace std;
const int Maxn=20;
vector <int> a,b;
bool vis[2010];
int n=10,ans;
inline int read()
{
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0' && ch<='9')s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
return s*w;
}
void dfs(int x,int tot)
{
if(x==5)
{
if(!vis[tot])
{
++ans;
}
vis[tot]=1;
return;
}
vector <int> oa,ob; //记录原始的vector状态,回溯时使用
oa=a,ob=b;
if(x%2)
{
for(int i=0;i<a.size();++i)
{
int tmp=a[i];
a.erase(a.begin()+i);
b.push_back(tmp);
dfs(x+1,tot-tmp);
a=oa,b=ob; //赋值为原来的状态
}
}
else
{
for(int i=0;i<b.size();++i)
{
int tmp=b[i];
b.erase(b.begin()+i);
a.push_back(tmp);
dfs(x+1,tot+tmp);
a=oa,b=ob;
}
}
}
int main()
{
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
//freopen("backforth.in","r",stdin);
//freopen("backforth.out","w",stdout);
for(int i=1;i<=n;++i)
{
int x=read();
a.push_back(x);
}
for(int i=1;i<=n;++i)
{
int x=read();
b.push_back(x);
}
dfs(1,1000);
printf("%d\n",ans);
return 0;
}