二分 + 动态规划30分求助
  • 板块P1504 积木城堡
  • 楼主Rinkan
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/7/29 21:08
  • 上次更新2024/7/29 22:14:41
查看原帖
二分 + 动态规划30分求助
695872
Rinkan楼主2024/7/29 21:08
#include<iostream>
#include<algorithm>
#include<cstring>

using namespace std;
const int N = 110;
int castal[N][N];
bool dp[N * N];
int st[N], sum[N];
int n;
int ifsatisfi(int x, int num) // 检测第x组城堡是否能满足当前高度
{
	memset(dp, false, sizeof(dp));
	dp[0] = true;
	for (int i = 1; i <= st[x]; i++)
	{
		for (int j = num; j >= castal[x][i]; j--)
		{
			if (dp[j - castal[x][i]] == true) dp[j] = true;
		}
	}
	if (sum[x] > num && dp[num] == false) return -2; // 如果城堡总高度大于当前所求的高度且当前高度不能被凑出,依然可以找到更大的高度
	else if (sum[x] <= num && dp[num] == false) return -1; // 如果城堡总高度小于等于当前所求高度,且当前高度不能被凑出,则需要找到小一点的高度
	else if (dp[num] == true) return 1; // 满足,找更大高度
}
bool judge(int mid)
{
	int state = 2;
	for (int i = 1; i <= n; i++)
	{
		int temp = ifsatisfi(i, mid);
		if (temp == -1) // 只要有一个城堡的高度小于当前所求的高度都需要降低要求
		{
			state = 1;
			break;
		}
	}
	if (state == 1) return false;
	else return true;
}
int main()
{
	cin >> n;
	for (int i = 1; i <= n; i++)
	{
		int a;
		cin >> a;
		int tar = 0;
		while (a != -1)
		{
			castal[i][++tar] = a;
			sum[i] += a;
			st[i] = tar;
			cin >> a;
		}
	}
	//for (int i = 1; i <= n; i++) cout << st[i] << endl;
	if (n == 1)
	{
		cout << sum[n] << endl;
		return 0;
	}
	int left = 1, right = 10000;
	while (left < right) // 二分合适的高度
	{
		int mid = (left + right + 1) / 2;
		if (judge(mid)) left = mid; //如果当前高度可以被满足,则还可以更高
		else right = mid - 1;
	}
	cout << left << endl;
	return 0;
}
2024/7/29 21:08
加载中...