题意:
先输入一个长度为10的01串,第i个数字为1表示你有重量为i的砝码无数个,第i个数字为0表示你没有重量为i的砝码,你需要按照以下规则在一个一开始平衡的天平上放上m个砝码
- 第1个砝码放在天平左边,第2个砝码放在天平的右边,第3个砝码放在天平左边……依次交替,直到放完m个
- 每次放完砝码后,必须满足天平往当前这一侧倾斜(重量大于另一侧)
- 不能连续放两次相同质量的砝码
求出任意一组合法解,如果没有输出NO
思路:
dp[m][last][val]表示当前已经放了m个砝码,上一次放的砝码质量为last,且放完后天平的不平衡度为val的状态是否已经搜过
搜出一组解就直接在DFS时输出,搜不到就输出NO
复杂度O(10*10*m)
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<string>
#include<math.h>
#include<queue>
#include<stack>
#include<iostream>
using namespace std;
#define LL long long
#define mod 1000000007
int flag[12], dp[1005][12][12];
int Sech(int n, int last, int dis)
{
int i;
if(dp[n][last][dis])
return 0;
dp[n][last][dis] = 1;
if(n==1)
{
if(last==dis)
{
printf("YES\n%d", last);
return 1;
}
return 0;
}
if(dis>=last || dis==0)
return 0;
for(i=1;i<=10;i++)
{
if(flag[i]==0 || last==i)
continue;
if(Sech(n-1, i, last-dis))
{
printf(" %d", last);
return 1;
}
}
return 0;
}
int main(void)
{
int i, n, j;
for(i=1;i<=10;i++)
scanf("%1d", &flag[i]);
scanf("%d", &n);
for(i=1;i<=10;i++)
{
if(flag[i]==0)
continue;
for(j=0;j<=i;j++)
{
if(Sech(n, i, j))
{
puts("");
return 0;
}
}
}
printf("NO\n");
return 0;
}