日常训练2025-1-11

日常训练2025-1-11

P1091 [NOIP2004 提高组] 合唱队形

https://www.luogu.com.cn/problem/P1091

思路

枚举一条分界线,分界线左边是从左到右求最长上升子序列,分界线右边从右到左求最长上升子序列。

然后计算答案即可。

代码

#include <bits/stdc++.h>

typedef std::pair<long long, long long> pll;
typedef std::pair<int, int> pii;
#define INF 0x3f3f3f3f
#define MOD 998244353
using i64 = long long;
const int N = 1e5+5;

void solve(){
	int n = 0;
	std::cin >> n;

	std::vector<int> v(n+1);
	for (int i = 1; i <= n; i++) std::cin >> v[i];

	std::vector<int> f(n+1, 1), g(n+1, 1);
	f[1] = 1;
	for (int i = 2; i <= n; i++){
		for (int j = i - 1; j >= 1; j--){
			if (v[i] > v[j] && f[i] <= f[j] + 1){
				f[i] = f[j] + 1;
			}
		}
	}

	g[n] = 1;
	for (int i = n - 1; i >= 1; i--){
		for (int j = i + 1; j <= n; j++){
			if (v[i] > v[j] && g[i] <= g[j] + 1){
				g[i] = g[j] + 1;
			}
		}
	}
	int ans = 0;
	for (int i = 1; i <= n; i++){
		ans = std::max(ans, f[i]+g[i]-1);
	}

	std::cout << n - ans << '\n';
}

signed main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	std::cout<<std::setiosflags(std::ios::fixed)<<std::setprecision(2);
	int t = 1, i;
	for (i = 0; i < t; i++){
		solve();
	}
	return 0;
}

P1541 [NOIP2010 提高组] 乌龟棋

https://www.luogu.com.cn/problem/P1541

思路

多维背包问题

题解:https://www.luogu.com.cn/article/6maja666

题解已经讲的非常清楚,不再过多赘述。

代码

#include <bits/stdc++.h>

typedef std::pair<long long, long long> pll;
typedef std::pair<int, int> pii;
#define INF 0x3f3f3f3f
#define MOD 998244353
using i64 = long long;
const int N = 1e5+5;

int f[41][41][41][41];
void solve(){
	int n, m;
	std::cin >> n >> m;
	std::vector<int> v(n+1);
	for (int i = 1; i <= n; i++){
		std::cin >> v[i];
	}

	int count[5] = {0};

	for (int i = 0; i < m; i++){
		int a;
		std::cin >> a;
		count[a]++;
	}
	f[0][0][0][0] = v[1];
	for (int a = 0; a <= count[1]; a++){
		for (int b = 0; b <= count[2]; b++){
			for (int c = 0; c <= count[3]; c++){
				for (int d = 0; d <= count[4]; d++){
					int r = 1 + a + b*2 + c*3 + d*4;
					if (a != 0) f[a][b][c][d] = std::max(f[a][b][c][d], f[a-1][b][c][d] + v[r]);
					if (b != 0) f[a][b][c][d] = std::max(f[a][b][c][d], f[a][b-1][c][d] + v[r]);
					if (c != 0) f[a][b][c][d] = std::max(f[a][b][c][d], f[a][b][c-1][d] + v[r]);
					if (d != 0) f[a][b][c][d] = std::max(f[a][b][c][d], f[a][b][c][d-1] + v[r]);

				}
			}
		}
	}

	std::cout << f[count[1]][count[2]][count[3]][count[4]];
}

signed main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	std::cout<<std::setiosflags(std::ios::fixed)<<std::setprecision(2);
	int t = 1, i;
	for (i = 0; i < t; i++){
		solve();
	}
	return 0;
}

P1868 饥饿的奶牛

https://www.luogu.com.cn/problem/P1868

思路

一种做法是定义\(f[i]\):前i个区间能选到的最大数量

第二种做法是定义\(f[i]\):前i个格子能选到的最大数量

代码:第一种做法

#include <bits/stdc++.h>

typedef std::pair<long long, long long> pll;
typedef std::pair<int, int> pii;
#define INF 0x3f3f3f3f
#define MOD 998244353
using i64 = long long;
const int N = 1e5+5;

struct unit{
	int head, tail, val;
};

bool cmp(unit a, unit b){
	return a.tail < b.tail;
}



void solve(){
	int n;
	std::cin >> n;

	std::vector<unit> v(n+1);

	for (int i = 1; i <= n; i++){
		int x, y;
		std::cin >> x >> y ;
		v[i].head = x;
		v[i].tail = y;
		v[i].val = y - x + 1;
	}

	std::sort(v.begin()+1, v.end(), cmp);

	auto lower_bound = [&](int l, int r, int key) -> int{
		int ans = 0;
		while (l < r){
			int mid = (r+l+1)>>1;
			if (v[mid].tail < key) l = mid;
			else r = mid - 1;
		}

		return l;
	};

	std::vector<int> f(n+1);
	for (int i = 1; i <= n; i++){
		f[i] = std::max(f[i-1], f[lower_bound(0, i, v[i].head)] + v[i].val);
	}

	std::cout << f[n] << '\n';
}

signed main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	std::cout<<std::setiosflags(std::ios::fixed)<<std::setprecision(2);
	int t = 1, i;
	for (i = 0; i < t; i++){
		solve();
	}
	return 0;
}

Tokitsukaze and Short Path (minus)

https://ac.nowcoder.com/acm/contest/67742/J

思路

题目中出现的任何含义不明的数学公式都应该化为有具体含义的公式

这道题的核心就是将绝对值符号打开。

代码

#include <bits/stdc++.h>

typedef std::pair<long long, long long> pll;
typedef std::pair<int, int> pii;
#define INF 0x3f3f3f3f
#define MOD 998244353
using i64 = long long;
const int N = 1e5+5;

void solve(){
	int n;
	std::cin >> n;
	std::vector<int> v(n+1);
	for (int i = 1; i <= n; i++) std::cin >> v[i];

	std::sort(v.begin(), v.end());

	int pos = std::upper_bound(v.begin()+1, v.end(), v[1]*2) - v.begin();

	i64 ans = 0;

	for (int i = 1; i < pos; i++){
		ans += 1LL * (n-i) * 2 * v[i];
	}

	for (int i = pos; i <= n; i++){
		ans += 1LL * (n-i) * 4 * v[1];
	}

	std::cout << ans * 2 << '\n';
}

signed main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	std::cout<<std::setiosflags(std::ios::fixed)<<std::setprecision(2);
	int t = 1, i;
	std::cin >> t;
	for (i = 0; i < t; i++){
		solve();
	}
	return 0;
}
posted @ 2025-01-11 12:36  califeee  阅读(29)  评论(0)    收藏  举报