20230605 solution ( medic + fishing + snow + happy )

我竟然还记得填坑 感动

T1
典中典的背包板子 没啥好说的
code:

#include <bits/stdc++.h>
#define ll long long //其实不用开 但是以防万一
using namespace std;

const int N = 0x0d00;
ll f[N], g[N];
int T, M;

int main() {
	scanf("%d%d", &T, &M);
	for (int i = 1; i <= M; ++i) {
		int t, v;
		scanf("%d%d", &t, &v);
		memcpy(g, f, sizeof f );
		for (int j = t; j <= T; ++j) f[j] = max(g[j], g[j - t] + v);
	}
	printf("%lld", f[T]);
	
	return 0;
}

T2
看起来其实有点像背包的样子 但是我还是倾向于往普通 dp 的方向想
我们考虑转移 首先第 i 个鱼塘的状态一定是由第 i - 1 个鱼塘转移过来
然后我们考虑状态之间的关系 发现我们可以枚举离开第 i - 1 个鱼塘的时间 那么就会对第 i 个鱼塘的后面一段区间有影响
我们可以维护在第 i 个鱼塘钓 j 分钟鱼的收获
这里选择刷表转移 有两个需要注意的点:

  • 刷表要把 i + 1 行一直到 T 全部刷满 即就算没鱼可钓也要转移 防止后续转移出现问题
  • 可以选择在这个鱼塘啥也不调 所以枚举钓鱼时间要从 0 开始
    code:
#include <bits/stdc++.h>
#define ll long long
using namespace std;

const int N = 0x0d00;
const int M = 101;
ll f[M][N];
ll val[M][N];
int t[M], rel[M], maxtime[M];
int n, T;
ll ans;

void init() {
	for (int i = 1; i <= n; ++i) {
		maxtime[i] = 1 + val[i][1] / rel[i];
//		cout << maxtime[i] << endl;
		for (int j = 2; j <= maxtime[i]; ++j) val[i][j] = val[i][j - 1] - rel[i];
		for (int j = 2; j <= T; ++j) val[i][j] += val[i][j - 1];
//		cout << endl;
	}
}

void dp() {
	int st = 0;
	for (int i = 0; i < n; ++i) {
		st += t[i];
		for (int j = st; j <= T; ++j) {
			for (int k = 0; k + j + t[i + 1] <= T; ++k) {
//				if (i == 1 && j + k + t[i] == 1) cout << j << " " << k << " " << t[i] << endl;
				f[i + 1][j + k + t[i + 1]] = max(f[i + 1][j + k + t[i + 1]], f[i][j] + val[i + 1][k]);
				ans = max(ans, f[i + 1][j + k + t[i + 1]]);
			}
		}
	}
}

int main() {
//	scanf("%d", &n);
	for (int i = 1; i <= n; ++i) scanf("%d", &val[i][1]);
	for (int i = 1; i <= n; ++i) scanf("%d", &rel[i]);
	for (int i = 2; i <= n; ++i) scanf("%d", &t[i]);
	scanf("%d", &T);
	
	init();
	dp();
	
//	for (int i = 1; i <= n; ++i) {
//		for (int j = 1; j <= T; ++j) cout << f[i][j] << " ";
//		cout << endl;
//	}
	
	printf("%lld",ans);
	
	return 0;
}

T3
超级大毒瘤 题干没翻译明白而且还漏信息
原题一定保证是一个回路 并且一条道要扫两遍
所以直接计算所有道路的长度然后乘 2 除时间即可
但是这个不像原题有那个奇怪的多测 赢!
code:

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

double ans;

void work() {
	ans *= 2;
	ans /= 1000;
	double time = ans / 20.0;
	ll h = floor(time);
	ll m = round((time - h) * 60);
	if (m == 60) {
		m = 0;
		++h;
	}
	printf("%lld:%lld",h,m);
}

int main() {
	freopen("data.txt", "r", stdin);
	
	ll x, y;
	scanf("%lld%lld", &x, &y);
	ll x1, x2, y1, y2;
	while (scanf("%lld%lld%lld%lld", &x1, &y1, &x2, &y2) != EOF) {
		ans += sqrt(pow(x1 - x2, 2.0) + pow(y1 - y2, 2.0));
	}
	work();
	
	return 0;
}

T4
小清新背包类板子题 也没啥好说的
code:

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

const int N = 1e5 + 0721;
ll f[N], g[N];
int m, n;

int main() {
	scanf("%d%d", &m, &n);
	for (int i = 1; i <= n; ++i) {
		int val, imp;
		scanf("%d%d", &val, &imp);
		memcpy(g, f, sizeof f );
		for (int j = val; j <= m; ++j) f[j] = max(g[j], g[j - val] + val * imp);
	}
	printf("%lld",f[m]);
	
	return 0;
}
posted @ 2023-06-17 17:48  Steven24  阅读(9)  评论(0编辑  收藏  举报