学习C++从娃娃抓起!记录下在学而思小猴编程学习过程中的题目,记录每一个瞬间。侵权即删,谢谢支持!
附上汇总贴:小猴编程C++ | 汇总-CSDN博客
【题目描述】
小明接到了
n
n
n个工作,第
i
i
i个工作的截至日期是
d
i
d_i
di天,需要消耗连续的
c
i
c_i
ci天时间才能完成。具体地说,要完成第
i
i
i个工作,需要选择一个
c
i
≤
k
≤
d
i
c_i\le k\le d_i
ci≤k≤di的整数
k
k
k,从第
k
−
c
i
+
1
k-c_i+1
k−ci+1天到第
k
k
k天持续做这个工作。期间不能做其他工作。
完成第
i
i
i个工作可以得到
s
i
s_i
si元报酬。
从第
1
1
1天开始,小明通过选择合适的工作,最多可以获得的报酬是多少元?
【输入】
第
1
1
1行,
1
1
1个正整数
n
n
n。
接下来
n
n
n行,每行
3
3
3个正整数
d
i
,
c
i
,
s
i
d_i,c_i,s_i
di,ci,si。
【输出】
1
1
1个整数,小明可以获得的最多报酬。
【输入样例】
3
7 3 20
3 2 10
5 3 15
【输出样例】
35
【代码详解】
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 5005;
struct Work { // 定义结构体
int c, d, s;
}w[N];
bool cmp(Work x, Work y) // 按照截至日期从小到大排序
{
return x.d < y.d;
}
int n;
LL dp[N];
int main()
{
scanf("%d", &n); // 输入n
for (int i=1; i<=n; i++) { // 输入n个任务的截至日期、消耗天数和报酬
scanf("%d%d%d", &w[i].d, &w[i].c, &w[i].s);
}
sort(w+1, w+n+1, cmp); // 按照截至日期从小到大排序
for (int i=1; i<=n; i++) { // 使用一维背包(滚动数组实现)
for (int j=w[i].d; j>=w[i].c; j--) {
dp[j] = max(dp[j], dp[j-w[i].c]+w[i].s); // dp[j-w[i].c]不做i个工作的报酬加上w[i].s,即i个工作的报酬
}
}
LL ans = 0;
for (int j=0; j<=5000; j++) { // 遍历5000天,计算报酬的最大值
ans = max(ans, dp[j]);
}
printf("%lld\n", ans);
return 0;
}
【运行结果】
3
7 3 20
3 2 10
5 3 15
35