51nod1636 教育改革

原题链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1636

思路:先按难度系数排序,然后定义dp[i][j][k]表示,第i天安排第j门课程,作业量为 第j们课程的最小作业量+k的前i天最大作业量之和,之所以这样定义k,是因为课程的最小最大作业量范围太大,但是差值很小,所以可以定义为在区间内的位置来定义,然后转移就好

AC代码:

#include<bits/stdc++.h>
using namespace std;
const int MOD = 1e9 + 7;
const int MAXN = 1e5 + 5;
const double PI = acos(-1.0);

struct crouse {
	long long a, b;
	int  c;
	bool operator < (const crouse&cr)const {
		return c < cr.c;
	}
}crouses[55];

long long dp[55][55][105];
int n, m, k;
void solve() {
	memset(dp, -1, sizeof(dp));
	for (int i = 1; i <= m; i++) {
		for (int j = 0; j <= crouses[i].b - crouses[i].a; j++) {
			dp[1][i][j] = crouses[i].a + j;
		}
	}
	for (int i = 2; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			for (int num = 0; num <= crouses[j].b - crouses[j].a; num++) {
				for (int t = 1; crouses[t].c < crouses[j].c; t++) {
					long long v = crouses[j].a + num - k;
					if (crouses[t].a <= v&&crouses[t].b >= v && dp[i - 1][t][v - crouses[t].a] != -1) {
						dp[i][j][num] = max(dp[i][j][num], dp[i - 1][t][v - crouses[t].a] + num + crouses[j].a);
					}
					v += k;
					if (v%k == 0 && crouses[t].a <= v / k && crouses[t].b >= v / k && dp[i - 1][t][v / k - crouses[t].a] != -1) {
						dp[i][j][num] = max(dp[i][j][num], dp[i - 1][t][v / k - crouses[t].a] + num + crouses[j].a);
					}
				}
			}
		}
	}
}
int main() {
	scanf("%d %d %d", &n, &m, &k);
	for (int i = 1; i <= m; i++) {
		scanf("%lld %lld %d", &crouses[i].a, &crouses[i].b, &crouses[i].c);
	}
	sort(crouses + 1, crouses + 1 + m);
	solve();
	long long ans = -1;
	for (int i = 1; i <= m; i++) {
		for (int j = 0; j <= crouses[i].b - crouses[i].a; j++) {
			ans = max(ans, dp[n][i][j]);
		}
	}
	if (ans == -1)printf("NO\n");
	else printf("YES\n%lld\n", ans);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值