蓝桥杯-枚举模板题
- 滑雪课程设计 P3650
- 新的家乡 P8587
- 枚举子集 B3622
- Air Cownditioning P9011
滑雪课程设计 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';}elsecout << '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;
}