机试-搜索专题
深搜
堆和栈的区别:
https://www.cnblogs.com/myblesh/archive/2012/03/14/2396409.html
定义全局变量或者自己malloc,栈的空间是有限的。
背包问题
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <stack>
#include <map>
#include <string>
#include <string.h>
#include <algorithm>
#include <math.h>
using namespace std;
// 输出背包问题的最佳方案
const int maxn = 20000;
int n,v;
int w[maxn];
int c[maxn];
vector<int> tmp,ans;
int maxc;
void dfs(int i,int sumw,int sumc)
{
if (i == n)
{
if (sumc > maxc)
{
maxc = sumc;
ans = tmp; // the way of vector assign
}
return ;
}
if (sumw+w[i] <= v)
{
tmp.push_back(i);
dfs(i+1,sumw+w[i],sumc+c[i]);
tmp.pop_back();
}
dfs(i+1,sumw,sumc);
}
int main()
{
while (cin>>n>>v)
{
for (int i=0;i<n;i++)
cin >> w[i];
for (int i=0;i<n;i++)
cin >> c[i];
dfs(0,0,0);
for (int i=0;i<ans.size();i++)
cout << ans[i] << ' ';
cout << endl;
cout << maxc << endl;
}
return 0 ;
}
N个数选K个使平方和最大且和为X
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <stack>
#include <map>
#include <string>
#include <string.h>
#include <algorithm>
#include <math.h>
using namespace std;
// 从N个数中选择K个数,使和为x的基础上平方和最大
const int maxn = 2000;
int n,k,x;
int maxsum;
vector<int> tmp,ans;
int a[maxn];
void dfs(int i,int num,int sum,int psum)
{
// i 代表第i个被选择的数,num代表一共挑选的数的个数,sum为其和,psum为平方和
if (i==n)
{
if (psum > maxsum && num == k && sum == x)
{
maxsum = psum;
ans = tmp;
}
return ;
}
dfs(i+1,num,sum,psum);
if (sum+a[i]<=x)
{
tmp.push_back(a[i]);
dfs(i+1,num+1,sum+a[i],psum+a[i]*a[i]);
tmp.pop_back();
}
}
int main()
{
while (cin>>n>>k>>x)
{
maxsum = 0;
for (int i=0;i<n;i++)
cin >> a[i];
dfs(0,0,0,0);
for (int i=0;i<ans.size();i++)
cout << ans[i] << ' ';
cout << endl;
cout << maxsum << endl;
}
return 0 ;
}
// 1.127s
void dfs(int i,int num,int sum,int psum)
{
// K个并且和为X时才判断
if (num == k && sum == x)
{
if (sum > maxsum)
{
maxsum = sum;
ans = tmp;
}
return ;
}
// 其他情况直接return
if (i>n-1 || num > k || sum>x)
return ;
if (a[i]+sum <= x)
{
tmp.push_back(i);
dfs(i+1,num+1,sum+a[i],psum+a[i]*a[i]);
tmp.pop_back();
}
dfs(i+1,num,sum,psum);
}
codeforces round 479 D divide by three, multiple by two
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <stack>
#include <map>
#include <string>
#include <string.h>
#include <algorithm>
#include <math.h>
using namespace std;
int n;
long long a[101];
bool visited[101];
long long f[101];
bool dfs(int &k)
{
if (k==n)
return true;
long long x = f[k-1];
for (int i=0;i<n;i++)
{
if (visited[i])
continue;
if ((a[i] == x/3 && (x%3==0)) || a[i] == x*2)
{
f[k++] = a[i];
visited[i] = true;
if (dfs(k)) return true;
visited[i] = false;
k--;
}
}
return false;
}
int main()
{
int k;
while (cin>>n)
{
for (int i=0;i<n;i++)
{
cin >> a[i];visited[i] = false;
}
k = 0;
for(int i=0;i<n;i++)
{
visited[i] = true;
f[k++] = a[i];
if (dfs(k)) break; // 只要找到一组就直接break,不用继续循环了
visited[i] = false;
k--;
}
for (int i=0;i<n;i++)
cout << f[i] <<' ';
cout << endl;
}
return 0 ;
}
return true / false / break 是为了在找到正确答案后立即输出而不是继续循环到末尾
解法2
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <stack>
#include <map>
#include <string>
#include <string.h>
#include <algorithm>
#include <math.h>
using namespace std;
// divide by three, multiple by two
int n;
long long a[101];// 8B 2^64 = 1024^6 = e^18
vector<long long >ans;
bool flag,visited[101] ;
void dfs(int i,int sum) // i: the i th number ; sum:selected number
{
if (sum==n)
{
for (int i=0;i<n-1;i++)
cout << ans[i] << ' ';
cout << ans[n-1]<<endl;
flag = true;
return ;
}
//4 8 6 3 12 9
for (int j=0;j<n;j++)
{
if (i!=j && !visited[j])
{
if ((a[j]==a[i]/3 && a[i]%3==0) || a[j] == a[i]*2 )
{
ans.push_back(a[j]);visited[j]=true;
dfs(j,sum+1);
if (!flag)
{
ans.pop_back();visited[j] = false;
}
}
}
}
}
int main()
{
while (cin>>n)
{
for (int i=0;i<n;i++)
{
cin >> a[i];visited[i]=false;
}
ans.clear();
flag = false;
for (int i=0;i<n;i++)
{
ans.push_back(a[i]);visited[i]=true;
dfs(i,1);
ans.pop_back();visited[i] = false;
}
}
return 0 ;
}
全排列
- 10 min
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <stack>
#include <map>
#include <string>
#include <string.h>
#include <algorithm>
#include <math.h>
using namespace std;
// 全排列
int n,sum;
bool visited[101];
vector<int> ans;
void dfs(int sum)
{
if (sum == n)
{
for (int i=0;i<n-1;i++)
cout << ans[i] <<" ";
cout << ans[n-1] << endl;
return;
}
for (int i=1;i<=n;i++)
{
if (!visited[i])
{
visited[i]= true;
ans.push_back(i);
dfs(sum+1);
visited[i]= false;
ans.pop_back();
}
}
}
int main()
{
while (cin>>n)
{
for (int i=1;i<=n;i++)
{
visited[i] = false;
}
ans.clear();
dfs(0); // 选择0个元素
}
return 0 ;
}
组合 递归
- 15min
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <stack>
#include <map>
#include <string>
#include <string.h>
#include <algorithm>
#include <math.h>
using namespace std;
// 递归 求组合
int n,r,num; // num:selected numbers
vector<int > ans;
void dfs(int i,int num)
{
// 判断第I个数是否要被选择
if (i == n)
{
if (num == r)
{
for (int i=0;i<r-1;i++)
cout << ans[i] <<" ";
cout << ans[r-1] << endl;
}
return;
}
ans.push_back(i+1);
dfs(i+1,num+1);
ans.pop_back();
dfs(i+1,num);
}
int main()
{
while (cin>>n>>r)
{
ans.clear();
dfs(0,0);//
}
return 0 ;
}
组合 非递归
?????????????????????????????
#define _CRT_SECURE_NO_WARNINGS
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <vector>
#include <string>
#include <queue>
#include <stack>
#include <map>
#include <set>
using namespace std;
void permutation(int n, int m)
{
vector<int> combine;
stack<int> buf;
bool pop = false;
int top;
buf.push(1);
combine.push_back(1);
while (buf.size())
{
if (combine.size() == m)
{
for (int i = 0; i < m; ++i)
{
printf("%d", combine[i]);
if (i != m - 1)
printf(" ");
}
printf("\n");
pop = true;
}
top = buf.top() + 1;
if (top == n + 1)
{
pop = true;
buf.pop();
combine.pop_back();
continue;
}
if (pop)
{
buf.pop();
combine.pop_back();
pop = false;
}
if (top <= n)
{
buf.push(top);
combine.push_back(top);
}
}
}
int main()
{
#ifdef _DEBUG
freopen("data.txt", "r+", stdin);
#endif // _DEBUG
int n, m, PS = 0;
while (cin >> n >> m)
{
permutation(n, m);
}
return 0;
}
组合数+判断素数
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <stack>
#include <map>
#include <string>
#include <string.h>
#include <algorithm>
#include <math.h>
using namespace std;
// 递归 求组合
int n,k,num,ans,ans_num; // num:selected numbers
int a[21];
bool visited[21];
bool isSu(int x)
{
for (int i=2;i<sqrt(x)+1;i++)
{
if (x%i == 0)
{
return false;
}
}
return true;
}
void dfs(int i,int num)
{
// 判断第I个数是否要被选择
if (i == n)
{
if (num == k && isSu(ans))
{
ans_num++;
}
return;
}
if (num+1 <= k )
{
ans += a[i+1];
dfs(i+1,num+1);
ans -= a[i+1];
}
dfs(i+1,num);
}
int main()
{
while (cin>>n>>k)
{
for (int i=1;i<=n;i++)
{
cin >> a[i]; visited[i]= false;
}
ans = 0;ans_num = 0;
dfs(0,0);
cout << ans_num << endl;
}
return 0 ;
}
N皇后
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <stack>
#include <map>
#include <string>
#include <string.h>
#include <algorithm>
#include <math.h>
using namespace std;
// N皇后问题
int n,num;
bool visited[11];
vector<int> ans;
bool flag = false;
bool isok(int i,int j)
{
// 判断第I行皇后能否放在J个列
// 1. 不可能同一行,因为I从1-n
// 2. 同一列
if (visited[j])
return false;
// 3. 对角线
// i,j / k, l |i-k| = |k-l| 时两个点在对角线上
for (int k = 1;k<i;k++)
{
if (abs(k-i) == abs(ans[k-1]-j))
return false;
}
return true;
}
void dfs(int i)
{
if (i==n)
{
flag = true;
for (int j=0;j<n-1;j++)
cout << ans[j] << " ";
cout << ans[n-1] << endl;
return ;
}
for (int j=1;j<=n;j++)
{ // j : column
if (isok(i+1,j))
{
visited[j] = true;
ans.push_back(j);
dfs(i+1);
visited[j] = false;
ans.pop_back();
}
}
}
int main()
{
while (cin>>n)
{
ans.clear();
for (int i=0;i<=n;i++)
visited[i] = false;
dfs(0);
if (!flag)
cout<<"no solute!" <<endl;
}
return 0 ;
}
迷宫
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <stack>
#include <map>
#include <string>
#include <string.h>
#include <algorithm>
#include <math.h>
using namespace std;
// 走迷宫
int n,m;
int a[101][16];
struct point
{
int x,y;
};
point s,e,t;
vector<point> ans;
void print()
{
for (int i=0;i<ans.size()-1;i++)
{
cout << "("<<ans[i].x<<","<<ans[i].y<<")->";
}
cout << "("<<ans[ans.size()-1].x<<","<<ans[ans.size()-1].y<<")"<<endl;
}
int dir[4][2] = {
0,-1,
-1,0,
0,1,
1,0
};
void dfs(point p)
{ // p:当前位置
if (p.x == e.x && p.y == e.y)
{
print();
return;
}
if (p.x<1 || p.x > n || p.y < 1 || p.y > m)
return ; // meet border return
if (a[p.x][p.y] == 0)
return ; // meet wall return
for (int i=0;i<4;i++)
{
t = p;
// 四个方向即四个分支可以深搜
t.x = p.x+dir[i][0];
t.y = p.y+dir[i][1];
// 已经访问过的点再往下深搜的过程中不会再次访问,可以设为wall
a[p.x][p.y] = 0;
ans.push_back(t);
dfs(t);
a[p.x][p.y] = 1;
ans.pop_back();
}
}
int main()
{
while (cin>>n>>m)
{
for (int i=1;i<=n;i++)
{
for (int j=1;j<=m;j++)
{
cin >> a[i][j];
}
}
ans.clear();
cin >> s.x >> s.y;
cin >> e.x >> e.y;
ans.push_back(s);
dfs(s);
}
return 0 ;
}
- 本地运行正确但提交不正确
jugs
???
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <stack>
#include <map>
#include <string>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <queue>
using namespace std;
int ca,cb,n;
struct node
{
int x,y;
struct node *parent;
string word;
}s,e,tmp,cur;
queue<node> q;
vector<string> w;
int main()
{
while (cin>>ca>>cb>>n)
{
while (!q.empty())
q.pop();
w.clear();
s.x = 0;s.y = 0;s.parent = NULL;
e.y = n;
q.push(s);
while (!q.empty())
{
cur = q.front();
q.pop();
// ÅжÏÊÇ·ñΪ×îÖÕ̬
if (cur.y == e.y)
{
string t = "success";
w.push_back(t);
struct node *p;p=&cur;
while (p->parent!=NULL)
{
w.push_back(p->word);
p = p->parent;
}
for (int i = w.size()-1;i>=0;i--)
{
cout << w[i] << endl;
}
}
if (cur.x < ca)
{
tmp = cur;
// A is not full
tmp.x = ca;
tmp.word = "fill A";
tmp.parent = &cur;
q.push(tmp);
}
if (cur.y < cb)
{
tmp = cur;
// B is not full
tmp.y = cb;
tmp.word = "fill B";
tmp.parent = &cur;
q.push(tmp);
}
if (cur.x > 0)
{
tmp = cur;
// A is not empty
tmp.x = 0;
tmp.word = "empty A";
tmp.parent = &cur;
q.push(tmp);
}
if (cur.y > 0)
{
tmp = cur;
// B is not empty
tmp.y = 0;
tmp.word = "empty B";
tmp.parent = &cur;
q.push(tmp);
}
if (cur.x > 0 && cur.y < ca)
{
tmp = cur;
if (cur.x >= cb-cur.y) // x more than capacity of B
{
tmp.y = cb;
tmp.x = cur.x - cb + cur.y;
}
else
{
tmp.y = cur.x+cur.y;
tmp.x = 0;
}
tmp.word = "pour A B";
tmp.parent = &cur;
q.push(tmp);
}
if (cur.y > 0 && cur.x < ca)
{
tmp = cur;
// B have water and A has place to hold
if (cur.y >= ca-cur.x) // y more than capacity of A
{
tmp.x = ca;
tmp.y = cur.y - ca + cur.x;
}
else
{
tmp.x = cur.x+cur.y;
tmp.y = 0;
}
tmp.parent = &cur;
tmp.word = "pour B A";
q.push(tmp);
}
}
}
return 0 ;
}
- char 型迷宫定义成int型导致爆莫名奇妙的错误。
掉石头迷宫
???????????????
应该是迷宫状态更新的问题。 1.5小时
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <stack>
#include <map>
#include <string>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <queue>
using namespace std;
// 掉石头迷宫问题
int t1;
char a[9][9],t[9][9];
struct point
{
int x,y,t;
}s,e,tmp,cur;
vector<point> stone;
queue<point> q;
void printa(char a[9][9])
{
for (int i=1;i<=8;i++)
{
for (int j=1;j<=8;j++)
cout << a[i][j] << " ";
cout << endl;
}
}
void flush(char a[9][9]) // 石头状态刷新一次
{
/* int x1,y1;
for (int i=0;i<stone.size();i++)
{
x1 = stone[i].x;
y1 = stone[i].y;
a[x1][y1] = '.';
if (x1+1 <=8) // 超出边界的石头则删除了
a[x1+1][y1] = 'S';
}
*/
for (int i=1;i<9;i++)
{
for (int j=1;j<9;j++)
{
if (a[i][j] == 'S')
{
a[i+1][j] = 'S';
a[i][j] = '.';
}
}
}
}
int dir[9][2] =
{
-1,0,
-1,1,
0,1,
1,1,
1,0,
1,-1,
0,-1,
-1,-1,
0,0
};
bool judge(point tmp)
{
if (tmp.x < 1 || tmp.y >8 || tmp.y < 1 || tmp.y > 8)
return false;
if (a[tmp.x][tmp.y] == 'S' || t[tmp.x][tmp.y] == 'S') // 移动后所在位置有石头或移动后石头下落砸到自己
return false;
return true;
}
int main()
{
cin >> t1;
bool flag;
while (t1--)
{
flag = false;
// 输入迷宫
for (int i=1;i<=8;i++)
{
for (int j=1;j<=8;j++)
{
cin >> a[i][j]; t[i][j] = a[i][j];
}
}
/* 存石头位置
stone.clear();
for (int i=1;i<9;i++)
{
for (int j=1;j<9;j++)
{
if (a[i][j] == 'S')
{
tmp.x = i;tmp.y = j;
stone.push_back(tmp);
}
}
}
*/
// 清空队列
while (!q.empty())
q.pop();
// 初始化队列
s.x = 8;s.y = 1;e.x = 1;e.y = 8;s.t = 0;
q.push(s);
while (!q.empty())
{
cur = q.front();q.pop();
if (cur.x == e.x && cur.y == e.y)
{
flag = true;
break;
}
flush(t); // t是移动后的a
printa(t);
for (int i=0;i<9;i++)
{
tmp = cur;
tmp.x += dir[i][0];
tmp.y += dir[i][1];
tmp.t ++;
if (judge(tmp))
{
q.push(tmp);
}
}
flush(a);//a t 同步了
printa(a);
}
if (flag)
cout << "Yes" << endl;
else
cout << "No" << endl;
getchar();
}
return 0 ;
}
DP
斐波那契
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <stack>
#include <map>
#include <string>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <queue>
using namespace std;
int fib(int n)
{
if (n==1 || n==2)
return 1;
else
return fib(n-1)+fib(n-2);
}
int main()
{
int n;
while (cin >> n)
{
cout << fib(n) << endl;
}
return 0 ;
}
- n <= 30 最简单的递归,内存超限: 大量的重复的计算
- 方法:通过空间的损耗来提高计算的速度,一维数组DP记录每个数的数值,未计算过则设置为-1。
- 记忆化搜索 每个数仅算一遍
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <stack>
#include <map>
#include <string>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <queue>
using namespace std;
int dp[32];
int fib(int n)
{
if (n==1 || n==2) // 递归边界
{
return 1;
}
if (dp[n]!=-1)
return dp[n]; // 先判断我们的缓存里面有没有,有的话直接取出否则递归计算
else
{
dp[n] = fib(n-1)+fib(n-2);
return dp[n];
}
}
int main()
{
int n;
while (cin >> n)
{
for (int i=0;i<32;i++) dp[i] = -1;
cout << fib(n) << endl;
}
return 0 ;
}
最大连续子序列和
????????????????? 如何输出最大连续的子序列呢?
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <stack>
#include <map>
#include <string>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <queue>
using namespace std;
int dp[32];
bool flag[32];
int a[10001];
int main()
{
int n;
while (cin >> n)
{
for (int i=0;i<n;i++)
{cin >> a[i];flag[i] = false;}
dp[0] = a[0];
for (int i=1;i<n;i++)
{
dp[i] = max(a[i],dp[i-1]+a[i]);
}
}
return 0 ;
}
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <stack>
#include <map>
#include <string>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <queue>
using namespace std;
int dp[32];
bool flag[32][32];
int a[10001];
int main()
{
int n;
while (cin >> n)
{
for (int i=0;i<n;i++)
{cin >> a[i];}
for (int i=0;i<32;i++)
{
for (int j=0;j<32;j++)
flag[i][j] = false;
}
dp[0] = a[0]; flag[0][0] = true;
for (int i=1;i<n;i++)
{
dp[i] = max(a[i],dp[i-1]+a[i]);
if (dp[i] == a[i])
{
flag[i][i] = true;
}
else
{
for (int x=0;x<i;x++)
flag[i][x] = flag[i-1][x];
flag[i][i] = true;
}
}
int k = 0;
int max = dp[0];
for (int i=1;i<n;i++)
{
if (dp[i] > max)
{
max = dp[i]; k = i;
}
}
for (int i=0;i<n;i++)
{
if (flag[k][i])
cout << a[i] <<" ";
}
}
return 0 ;
}
- 运行错误? 还是格式错误?
最长上升子序列
http://codeup.cn/problem.php?cid=100000627&pid=0
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <stack>
#include <map>
#include <string>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <queue>
using namespace std;
int main()
{
int n;
int dp[32];
int a[10001];
while (cin >> n)
{
for (int i=0;i<n;i++)
{cin >> a[i];dp[i] = 1;}
for (int i=1;i<n;i++)
{
for (int j=0;j<i;j++)
{
if (a[j] < a[i])
{
dp[i] = max(dp[i],dp[j]+1);
}
}
}
sort(dp,dp+n);
cout << dp[n-1] << endl;
}
return 0 ;
}
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <stack>
#include <map>
#include <string>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <queue>
using namespace std;
const int maxn = 200001;
int a[maxn];
int n;
int dp[maxn];
int main()
{
while (cin>>n)
{
for (int i=0;i<n;i++)
cin >> a[i];
dp[0] = 1;
int ans = 0; // 最大dp值的下标
for (int i=1;i<n;i++)
{
for (int j=0;j<i;j++)
{
if (a[j] == a[i]-1)
{
dp[i] = max(dp[i],dp[j]+1); // 找到最大的
}
}
if (dp[i] > dp[ans])
{
ans = i;
}
}
cout << dp[ans] << endl;
vector<int> p;p.clear();
for (int i = ans,j=0;i>=0;i--)
{
if (a[i] == a[ans]-j)
{
p.push_back(i);j++;
}
}
for (int i=p.size()-1;i>0;i--)
cout << p[i]+1 <<" ";
cout << p[0]+1 << endl;
}
return 0 ;
}
time limited 超时了!
用map存储:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <stack>
#include <map>
#include <string>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <queue>
using namespace std;
const int maxn = 200001;
int a[maxn];
int n;
int dp[maxn];
map<int,int> m;
int main()
{
while (cin>>n)
{
m.clear();
for (int i=0;i<=n;i++)
m[i] = 0;
for (int i=1;i<=n;i++)
{
cin >> a[i];
m[a[i]] = m[a[i]-1]+1;
}
int ans = 0,k=0;
map<int,int>::iterator it;
for (it = m.begin();it !=m.end();it++)
{
if (it->second > ans)
{
ans = it->second;
k = it->first;
}
}
int pos = k - ans + 1;
cout << ans << endl;
for (int i=1;i<=n&&pos <= k;i++ )
{
if (a[i] == pos)
{
cout << i <<" ";
pos++;
}
}
}
return 0 ;
}
非常可乐
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <stack>
#include <map>
#include <string>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <queue>
using namespace std;
int coco,n,m;
struct status
{
int a,b,c,d;
}s,cur,tmp;
queue<status> q;
const int maxn = 101;
int v[maxn][maxn][maxn];
void pour(int a,int b,int c,int d)
{
if (!v[a][b][c])
{
v[a][b][c] = 1;
tmp.a = a;
tmp.b = b;
tmp.c = c;
tmp.d = d+1; // 未出现的状态才倒水,并加入队列
q.push(tmp);
}
}
int bfs(int a,int b,int c,int d) // d为倒水次数,a,b,c为杯中可乐量
{
while (!q.empty()) q.pop();
s.a = coco;s.b = s.c = s.d = 0; // 初始状态
q.push(s);
v[coco][0][0] = 1; // 该状态已入队过,为防止重复入队
while (!q.empty())
{
cur = q.front();q.pop();
if ((cur.a == coco/2 && cur.b == coco/2 )||(cur.a == coco/2 && cur.c == coco/2 ) || (cur.b == coco/2 && cur.c == coco/2 ) )
return cur.d;
//s->n:
if (cur.a > 0 && cur.b < n) // a has coco and b is not full
pour(cur.a - n + cur.b, n, cur.c, cur.d);
//s->m;
if ( cur.a > 0 && cur.c < m)
pour(cur.a - m + cur.c, cur.b, m, cur.d);
//n->s;
if (cur.b > 0 && cur.a < coco)
pour(cur.a + cur.b, 0, cur.c, cur.d);
//m->s;
if (cur.c > 0 && cur.a < coco )
pour(cur.a + cur.c, cur.b, 0, cur.d);
//n->m
if (cur.b > 0 && cur.c < m)
{
if(cur.b > m - cur.c)
pour(cur.a, cur.b - m + cur.c, m, cur.d);
else
pour(cur.a, 0, cur.b + cur.c, cur.d);
}
//m->n
if (cur.c > 0 && cur.b < n)
{
if(cur.c > n - cur.b)
pour(cur.a, n, cur.c - n + cur.b, cur.d);
else
pour(cur.a, cur.b + cur.c, 0, cur.d);
}
}
return 0;
}
int main()
{
int ans;
while (cin>>coco>>n>>m)
{
memset(v,0,sizeof(int)*maxn*maxn*maxn);
if (coco==0)
break;
if (coco%2 == 1)
{
cout<< "NO" << endl;continue;
}
ans = bfs(coco,0,0,0);
if ( ans > 0)
{
cout << ans << endl;
}
else
cout<< "NO" << endl;
}
return 0 ;
}
####导弹拦截系统:最长不降子序列
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <stack>
#include <map>
#include <string>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <queue>
using namespace std;
const int maxn = 1001;
int main()
{
int n;
int a[maxn];
int dp[maxn]; // 以I为结尾的不降子序列的长度
while (cin>>n)
{
for (int i=0;i<n;i++)
{
cin >> a[i]; dp[i] = 1;
}
int ans = 1;
for (int i=1;i<n;i++)
{
for (int j=0;j<i;j++)
{
if (a[j] < a[i])
{
dp[i] = max(dp[j]+1,dp[i]);
}
}
if (dp[i] > ans)
ans = dp[i];
}
cout <<ans<< endl;
}
return 0 ;
}