其他分享
首页 > 其他分享> > Codeforces Round #787 (Div. 3) F, G题题解

Codeforces Round #787 (Div. 3) F, G题题解

作者:互联网

Codeforces题解汇总

Codeforces Round #787 (Div. 3)

F. Vlad and Unfinished Business ( \(\color{#AAF}{1800}\) )

题意

给了点数为 \(n\) 的树,和 \(k\) 个必须到达的点,出发的起点 \(x\) 和 到达终点 \(y\),边权为 \(1\) ,询问从起点经过指定的
\(k\) 个点,最后到达 \(y\) 的最短路径花费, \(k\) 个点的访问顺序可以任意。

数据范围
\(1\leq k \leq n \leq 2 * 10^5\)

思路

Solution

#include<bits/stdc++.h>
typedef long long ll;
typedef std::pair<int, int> PII;
typedef std::pair<ll, ll> PLL;
typedef unsigned long long ull;
#define x first
#define y second
#define pb push_back
#define mkp make_pair
#define endl "\n"
using namespace std;
const int N = 2e5 + 10;
int n, k, x, y, ans;
vector<int> edge[N];
int dep[N];
bool st[N];

int dfs(int u, int p){
	int tot = 0;
	for(auto v: edge[u]){
		if(v == p) continue;
		dep[v] = dep[u] + 1;
		tot += dfs(v, u);
	}
	if(!tot && !st[u]) ans--;
	return tot + (st[u] == true);
}

int main(){
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	int T;
	cin >> T;
	while(T--){
		cin >> n >> k;
		cin >> x >> y;
		ans = n;
		vector<int> a(k + 1, 0);
		for(int i = 1; i <= k; i++){
			cin >> a[i];
			st[a[i]] = true;
		}
		st[x] = true, st[y] = true;
		for(int i = 1; i < n; i++){
			int u, v;
			cin >> u >> v;
			edge[u].pb(v);
			edge[v].pb(u);
		}
		dfs(x, -1);
		cout << 2 * (ans - 1) - dep[y] << endl;
		for(int i = 1; i <= n; i++){
			edge[i].clear();
			st[i] = false;
			dep[i] = 0;
		}
	}
    return 0;
}

G. Sorting Pancakes ( \(\color{#FB5}{2300}\) )

参考题解: Ximena, 严格鸽

题意
给了一个长度 \(n\) 的数组 \(a\) ,和保证为 \(m\), 每次只能将 \(a_i\) 减 1, \(a_{i-1}\; or\; a_{i+1}\) 加 1,询问最小的操作次数使 \(a\) 非严格递减。

数据范围
\(1\leq n,m \leq 250\)

思路

for(int i = 1; i <= n; i++){
    for(int j = 0; j <= m; j++){
        int mi = 0x3f3f3f3f;
        for(int k = 0; k <= m - j; k++) {
            mi = min(mi, dp[i - 1][j][k]);      // 转移 k 时,mi 记录了上一位数值为 [0, k] 的最小值,因此是合法的
            f[i][j + k][k] = min(f[i][j + k][k], mi + abs(s[i] - abs(j + k)));
        }
    }
}

Solution

#include<bits/stdc++.h>
typedef long long ll;
typedef std::pair<int, int> PII;
typedef std::pair<ll, ll> PLL;
typedef unsigned long long ull;
#define x first
#define y second
#define pb push_back
#define mkp make_pair
#define endl "\n"
using namespace std;
const int N = 260;
int n, m;
int a[N], s[N];
int dp[N][N][N];		
// 将数组翻转
// dp[i][j][k] 前i个数,和为j,最后一个数最大值为k 满足递增序列最小操作
int main(){
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	cin >> n >> m;
	for(int i = n; i >= 1; i--)
		cin >> a[i];
	for(int i = 1; i <= n; i++)
		s[i] = s[i - 1] + a[i];
	memset(dp, 0x3f, sizeof dp);
	dp[0][0][0] = 0;        // 前0个数,和为0,数最大值为0,操作次数为0
	for(int i = 1; i <= n; i++){
		for(int j = 0; j <= m; j++){
			int mi = 0x3f3f3f3f;
			for(int k = 0; k <= m - j; k++){
				mi = min(dp[i - 1][j][k], mi);
				dp[i][j + k][k] = min(dp[i][j + k][k], mi + abs((j + k) - s[i]));
			}
		}
	}
	int ans = 0x3f3f3f3f;
	for(int i = 0; i <= m; i++)
		ans = min(ans, dp[n][m][i]);
	cout << ans << endl;
    return 0;
}

标签:typedef,787,int,题解,cin,long,Div,dp,define
来源: https://www.cnblogs.com/Roshin/p/cfround787div3.html