浙江中医药大学暑期训练测试赛十
来源:互联网 发布:json字符串转json对象 编辑:程序博客网 时间:2024/04/28 16:19
Problem A: 英雄无敌3(1)
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 84 Solved: 14
[Submit][Status][Web Board]
Description
大家知道在英雄无敌3中,每个城堡都需要钱来维持建设,现在有一座很奇怪的金矿,它在第i天只产生si 元的钱,而且如果你在第i天拿到si 元的钱,那么你将在 xi 内(包括第i天)拿不到钱,而在yi天内(包括第i天)一定要再次拿钱。现在有一个着急的玩家,他现在已经拿了第一天的钱,他想知道他最多能拿到多少钱(包含第一天的钱)。
Input
第一行输入一个数t,代表测试案例数
每个案例先输入一个数n(n < =50000),代表总共有几天,接下来有n行,输入3个整数整数分别为si,xi,yi (0<=si<10000,0<=xi < yi)
Output
对于每组案例,输出一个正整数,代表他能拿到的最多钱数
Sample Input
431 1 22 2 33 3 431 1 32 2 43 3 5410 3 107 1 75 2 51 1 251 1 910 3 107 1 75 2 51 1 2
Sample Output
341113
HINT
先贴一下超时的代码:
说明下,这里的dp(i),表示前i天拿到的最大钱数。
超时的话是因为生成树的分支太多了,显然,从小往大的dp是很难得到优化,总之我是没有想到,因为从小
往大dp就相当于一个dfs的过程,实际上并非动态规划,即是,对于每一条可走的路径都走一遍,当然,前提是到达当前
节点时,其钱数比原先要多,但是,这样仍然耗时很多,因为并不能每次都能保留到最优解,而是需要不断对节点上的值
进行更新,于是想到逆序dp。怎样进行逆序dp呢,先说明一下,逆序dp,dp(i)所表示的含义,即第i天以后拿到的最大钱数。
这个时候我们利用先前超时的代码中,相当于一个dfs的过程,是可以每次都能保留到最优解的,为什么呢,我们假设第i天
是可以到达的,那么显然,dp(i)的大小只由后天它能到达的各天的钱数决定,于是,如果访问到了第i天,求出来一个dp(i),
即已经是最优解了,因为dp(i)只会包含它以后可到达天数的钱数,而不会受前面的影响。
以后到达第i天,都可以直接用到这个已经求出的最优解了,于是我们可以做出很大的优化,把一个最坏为O(n!)(这个
我也不太清楚,感觉应该是n!),优化到了O(n^2)
实际上是生成树的分支减少了很大一部分。
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
struct day {
int s;
int x;
int y;
}a[50005];
int dp[50005], Max = 0, n;
void make_dp(int l, int r, int v) {
for (int k = l; k <= r && k <= n; ++k) {
if (dp[k] < v + a[k].s) {
dp[k] = v + a[k].s;
make_dp(k + a[k].x, a[k].y + k - 1, dp[k]);
Max = max(dp[k], Max);
}
}
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
scanf("%d", &n);
for (int i = 1; i <= n; ++i) {
scanf("%d%d%d", &a[i].s, &a[i].x, &a[i].y);
if (a[i].x == 0)
a[i].x++;
dp[i] = 0;
}
dp[1] = a[1].s;
make_dp(a[1].x + 1, a[1].y, dp[1]);
printf("%d\n", Max);
}
return 0;
}
#include <cstdio>
#include <algorithm>
using namespace std;
struct day {
int s;
int x;
int y;
}a[50005];
int dp[50005], Max = 0, n;
void make_dp(int l, int r, int v) {
for (int k = l; k <= r && k <= n; ++k) {
if (dp[k] < v + a[k].s) {
dp[k] = v + a[k].s;
make_dp(k + a[k].x, a[k].y + k - 1, dp[k]);
Max = max(dp[k], Max);
}
}
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
scanf("%d", &n);
for (int i = 1; i <= n; ++i) {
scanf("%d%d%d", &a[i].s, &a[i].x, &a[i].y);
if (a[i].x == 0)
a[i].x++;
dp[i] = 0;
}
dp[1] = a[1].s;
make_dp(a[1].x + 1, a[1].y, dp[1]);
printf("%d\n", Max);
}
return 0;
}
#include <iostream>#include <cstdio>#include <algorithm>using namespace std;struct day { int s; int x; int y;}a[50005];int dp[50005], n;int make_dp(int l,int r) { int Max = 0; for(int k = l; k <= n && k <= r; ++k) { if(dp[k] == 0) { if(a[k].x + k <= n) dp[k] = max(dp[k], a[k].s + make_dp(a[k].x + k, a[k].y + k - 1)); else dp[k] = a[k].s; } Max = max(dp[k], Max); } return Max;}int main() { int t; scanf("%d", &t); while(t--) { scanf("%d", &n); for(int i = 1; i <= n; ++i) { scanf("%d%d%d", &a[i].s, &a[i].x, &a[i].y); if(a[i].x == 0) a[i].x++; dp[i] = 0; } printf("%d\n", make_dp(1,1)); } return 0;}
阅读全文
0 0
- 浙江中医药大学暑期训练测试赛十
- 浙江中医药大学暑期训练测试赛十 英雄无敌3(2) 数学公式
- 浙江中医药大学暑期训练测试赛八A
- 浙江中医药大学暑期训练测试赛八B
- 浙江中医药大学暑期训练测试赛八C
- 浙江中医药大学暑期训练测试赛八F
- 浙江中医药大学暑期训练测试赛八H
- 浙江中医药大学暑期训练测试赛八I
- 浙江中医药大学暑期训练测试赛八G
- 浙江中医药大学暑期训练测试赛八E
- 1591 浙江中医药大学
- 1531 浙江中医药大学
- 1066 浙江中医药大学ACM
- 1049 '最爱' 浙江中医药大学
- 1065 浙江中医药大学ACM OJ
- 寻找zcmu-2017浙江中医药大学程序设计
- 2017年浙江中医药大学大学生程序设计竞赛(重现赛)
- 2017年浙江中医药大学大学生程序设计竞赛(重现赛)-H剪纸
- noip2014 D2,T1无线网络发射器选址题解
- WPF ListView显示GridLine(可选)
- Android开发学习(12)Jersey构建RESTful后台服务
- Android 极光推送多进程造成的application运行两次
- tensorflow学习笔记-卷积,反卷积,空洞卷积
- 浙江中医药大学暑期训练测试赛十
- C# 批量生成随机密码必须包含数字和字母并用加密算法加密
- C++中STL(Standard Template Library)介绍
- C# 反射详解
- 修改Anaconda中的Jupyter Notebook当下工作路径
- 0816被充记录
- hpuoj【1293】合并数组(排序并处理重复数据)【水题】
- Mysql数据库与sql语言(四)---jdbc
- JQuery中$.ajax()方法参数详解