【蓝桥杯-枚举模板题】

滑雪课程设计 P3650

在这里插入图片描述
核心的思路是把数据规定在[i,i+17]里,不够的补,过大的减。枚举i以求最少的钱。

#include<bits/stdc++.h>
using namespace std;

int n;
int a[1010];

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);

	cin >> n;
	for (int i = 0; i < n; i++) cin >> a[i];
	int ans = 1e9;
	for (int low = 1; low <= 100; low++)
	{
		int high = low + 17;
		int sum = 0;

		for (int i = 0; i < n; i++)
		{
			if (a[i] < low) sum += (low - a[i]) * (low - a[i]);
			if (a[i] > high) sum += (a[i] - high) * (a[i] - high);

		}
		ans = min(ans, sum);

	}
	cout << ans;

	return 0;

}

新的家乡 P8587

在这里插入图片描述
核心思路是去枚举和。
[1,x-1];[2,x-2]~[x/2(下取整),x/2(上取整)]找两个元素的较少的那个。
特判比如3 3 3 3 3找6,此次不满足上一条,见代码特判处。

#include<bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
int a[N], cnt[N];

signed main()
{
	int n;
	cin >> n;
	for (int i = 0; i < n; i++)cin >> a[i];
	for (int i = 0; i < n; i++)cnt[a[i]]++;

	int ans1 = 0;
	int ans2 = 0;

	for (int x = 2; x <= 6000; x++)
	{
		int sum = 0;
		for (int i = 1; i <= x / 2; i++)//枚举小的一半 
		{
			if (i * 2 == x)//这个是特判,一般走else 
			{
				sum += cnt[i] / 2;
			}
			else
			{
				sum += min(cnt[i], cnt[x - i]);
			}
		}
		if (sum > ans1) ans1 = sum, ans2 = 1;
		else if (sum == ans1) ans2++;
	}
	cout << ans1 << ' ' << ans2;
	return 0;
}

枚举子集 B3622

在这里插入图片描述
核心思路是用位运算来模拟选与不选。

#include<bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
int n;

signed main()
{
	cin >> n;
	for (int i = 0; i < (1 << n); i++)
	{
		for (int j = n - 1; j >= 0; j--)//从大到小枚举 
		{
			if ((i >> j) & 1)
			{
				cout << 'Y';
			}
			else
				cout << 'N';
		}
		cout << endl;
	}
	return 0;
}

Air Cownditioning P9011

在这里插入图片描述
核心思路依然是用位运算枚举空调状态,但过程与数据更加复杂。

#include<bits/stdc++.h>
using namespace std;
#define int long long 
const int N = 110;
int a[N], b[N], p[N], cost[N], s[N], t[N], c[N];
int f[N], need[N];

signed main()
{
	int n, m;
	cin >> n >> m;

	for (int i = 1; i <= n; i++)
	{
		cin >> s[i] >> t[i] >> c[i];
		for (int j = s[i]; j <= t[i]; j++)
		{
			need[j] = max(c[i], need[j]);//更新要求
		}
	}

	for (int i = 1; i <= m; i++)cin >> a[i] >> b[i] >> p[i] >> cost[i];//以上为读入数据

	int ans = 0x3f3f3f3f;

	for (int state = 0; state < (1 << m); state++)//枚举空调用或不用
	{
		memset(f, 0, sizeof f);
		for (int j = 0; j < m; j++)
		{
			if ((state >> j) & 1)//第j台用不用
			{
				for (int x = a[j + 1]; x <= b[j + 1]; x++)
				{
					f[x] += p[j + 1];
				}
			}
		}
		bool flag = true;
		for (int i = 1; i <= 100; i++)
		{
			if (f[i] < need[i])//比如需要降低2度,结果就降了1度,那肯定不对了
			{
				flag = false;
			}
		}
		if (flag)
		{
			int sum = 0;
			for (int j = 0; j < m; j++)
			{
				if ((state >> j) & 1)
				{
					sum += cost[j + 1];
				}
			}
			ans = min(ans, sum);
		}
	}
	cout << ans;
	return 0;
}
  • 6
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值