列表

详情


NC206544. 环鸽的红包

描述

盼着盼着,新年终于来了!今年春节,环鸽要去赚大钱!他要抢很多很多的红包!

设抢红包时间一共有 秒,第 个红包环鸽可以在第 秒收集,里面有 元。如果环鸽抢了这个红包,那么他在第 秒之后才能继续抢红包(不包括 )。满足

环鸽不愿意多动脑子,于是他贪心地抢红包:如果第 秒的红包可以收集,他就会选择钱数最多的那个红包。如果有多个这样的红包,他就选择 最大的那个。

你突然得到了一个消息——环鸽没有抢到的红包,将全部归你!于是你决定去干扰环鸽抢红包。如果你在第 秒对环鸽喊 "嘤嘤嘤",环鸽就无法在这一秒抢红包。在下一秒,环鸽将继续贪心地抢红包。你最多可以对环鸽喊 次 “嘤嘤嘤”。

输入描述

第一行三个整数 

接下来 行代表 个红包,每行三个整数分别代表

输出描述

输出一个整数代表你采用最优策略后能拿到的钱数。

示例1

输入:

10 1 6
1 2 4
2 6 2
3 3 3
4 4 5
5 5 7
6 6 9

输出:

28

说明:

样例中,在第 \ 1 秒干扰环鸽。于是环鸽在第二秒抢到第 \ 2 个红包,然后他不能抢任何一个红包了。

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 320ms, 内存消耗: 160872K, 提交时间: 2020-05-23 14:10:49

#include <bits/stdc++.h>
#define MAXN 100005
#define MOD 1000000007
#define INF 1000000000000000
using namespace std;
int N,M,K;
struct node{
int ti=-1;
long long v=-1;
friend bool operator <(node a,node b)
{
    if(a.v!=b.v)return a.v>b.v;
    return a.ti>b.ti;
}
};
node bin[MAXN];
long long dp[MAXN][203];
int main()
{
   //freopen("testdata.in","r",stdin);
   cin>>N>>M>>K;
   long long sum=0;
   for(int i=1;i<=K;i++)
   {
       int f,t;long long w;
       cin>>f>>t>>w;
       node sub;sub.ti = t,sub.v = w;
       if(sub < bin[f])bin[f]=sub;
       sum += sub.v;
   }
   memset(dp,127,sizeof(dp));
   dp[1][0] = 0;
   for(int i=1;i<=N;i++)
      for(int j=0;j<=M;j++)
   {
       if(dp[i][j]>=INF)continue;
       if(bin[i].ti==-1)
       {
           dp[i+1][j]=min(dp[i][j],dp[i+1][j]);
       }
       else
       {
       if(j<200)dp[i+1][j+1]=min(dp[i+1][j+1],dp[i][j]);
       dp[bin[i].ti+1][j] = min(dp[bin[i].ti+1][j],dp[i][j]+bin[i].v);
       }
   }
   long long mint = INF;
   for(int i=0;i<=M;i++)
       mint=min(dp[N+1][i],mint);
   cout<<sum-mint<<endl;

   return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 191ms, 内存消耗: 165608K, 提交时间: 2020-05-23 14:53:21

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int read()
{
	int res = 0, f = 1; char c = getchar();
	while(!isdigit(c) && c != '-') c = getchar();
	if(c == '-') f = -1, c = getchar();
	while(isdigit(c)) res = (res<<3)+(res<<1)+(c^48), c = getchar();
	return res*f;
}

const int maxn = 1e5+10;
const LL inf = 4e18;
int n, m, k, nt[maxn], w[maxn];
LL sum, dp[maxn][210];

int main()
{
	n = read(); m = read(); k = read();
	for(int i = 1; i <= n; i++) nt[i] = i+1;
	for(int i = 1, u, v, d; i <= k; i++)
	{
		u = read(); v = read()+1; d = read();
		sum += d;
		if(w[u] < d || (w[u] == d && nt[u] < v))
		{
			nt[u] = v;
			w[u] = d;
		}
	}
	
	for(int i = 2; i <= n+1; i++)
	for(int j = 0; j <= m; j++) dp[i][j] = inf;
	
	for(int i = 1; i <= n; i++)
	for(int j = 0; j <= m; j++)
	{
		if(j > i-1) break;
		dp[nt[i]][j] = min(dp[nt[i]][j], dp[i][j]+w[i]);
		if(j < m) dp[i+1][j+1] = min(dp[i+1][j+1], dp[i][j]);
	}
	
	LL ans = inf;
	for(int i = 0; i <= m; i++) ans = min(ans, dp[n+1][i]);
	ans = sum-ans;
	printf("%lld\n", ans);
	return 0;
}

上一题