牛客IOI周赛22-提高组 华丽转身 C++

牛客IOI周赛22-提高组 华丽转身 C++

原题链接
在红星中学,一个年级一学年共有 n 场考试,每场考试都有 m 名同学参加,有一个巨佬叫李华 ,他已经不屑于通过AK考试来获得快感,于是他找到了一些另类的方法。
众所周知,班主任在每次考试后都会为相对上次考试排名进步了 50%50% (向下取整,eg:上次获得了第 5 名获得≤2 的排名即可获得华丽转身奖)的同学颁发华丽转身奖,在i场考试中获得华丽转身奖可以获得num_i份奖品(特别的,第一次考试不能获得华丽转身奖)。
而由于班主任不同时期的财政状况不同,所以每一次考试华丽转身奖的奖品份数也不尽相同。
因为李华太强了,他在每场考试中可以精准控制他的排名在 [l_i,r_i]
内,他想最大化获得奖品的份数,他在 1s 中内就算出了答案,现在想考考你!
输入描述:
第一行输入两个正整数 n,m ,分别表示考试的场数和参加考试的人数
接下来 n 行每行输入 3 个数 l_i,r_i,num_il
,表示第 i 场考试可以控制的排名区间为 [l_i,r_i]
,且若满足条件即可获得 num_i 份奖品
( 1≤ l_i ≤ r_i≤m)
输出描述:
输出仅一个数,表示最多获得的奖品份数。

输入案例

4 5
1 5 1
1 2 1
3 4 1
1 2 1

输出案例

2

解题思路

我暂时还有点懵,比如为啥没用m就把题a了,等我挖个坑好好想清楚
但是代码里面有解释关键部分操作
大伙可以先看看哈~

AC代码

#include <cstdio>
#include <algorithm>
using namespace std;
const int N=100001;
long long gett[N][2];//0表示没获奖,1表示获奖
long long l[N],r[N],v[N];
int main() {
    
    
	long long n,m;
	scanf("%d%d",&n,&m);
	gett[1][1]=-1e4;
	gett[1][0]=0;
	for(int i=1; i<=n; i++)
		scanf("%d %d %d",&l[i],&r[i],&v[i]);
	for(int i=2; i<=n; i++) {
    
    
		gett[i][0]=max(gett[i-1][0],gett[i-1][1]);//得到上次一考试的最大奖品份数
		gett[i][1]=-1e4;//初始化本次获奖状态
		long long sum=0;
		sum+=v[i];
				long long index=l[i];
		for(int j=i-1; j>=1; j--) {
    
    
	index*=2;
			if(r[j]>=index)
				index=max(index,l[j]);
			else//如果r[j]比index还小,就不可能获奖,跳出该循环
				break;
			gett[i][1]=max(gett[i][1],gett[j][0]+sum);//求一下该次获奖的最大分数
			sum+=v[j];//叠加sum
		}
	}
	printf("%d",max(gett[n][0],gett[n][1]));//有可能最后一次没获奖但是份数更大
}

附:初来乍到,如果有不足之处,恳请各位大牛指正,如果题解有错误或者没写清楚的地方也欢迎在评论区提问~

猜你喜欢

转载自blog.csdn.net/qq_34832548/article/details/113494672