Codeforces Round #197 (Div. 2): C. Xenia and Weights(记忆化搜索)

版权声明:本文为博主原创文章,你们可以随便转载 https://blog.csdn.net/Jaihk662/article/details/83901062

题意:

先输入一个长度为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;
}

猜你喜欢

转载自blog.csdn.net/Jaihk662/article/details/83901062
今日推荐