【解题报告】[JOISC 2014] 挂饰

【我也不知道什么TM的系列】JOISC 2014 挂饰

经典的传送门

写这篇文章来告诉大家写贪心的重要性

心路历程

看到这道题第一印象:woc 蓝题

看了一下样例:woc 水题

贪了60分:woc 不是水题

AT LAST,看题解改出来了

贪心

分析一下样例

貌似是先选了一个钩最多的然后挑val大于零的选

呦西,看来这题很水么,终于5分钟就能切一道蓝题力

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>

using namespace std;

const int maxn=2010;

inline int read()
{
	int w=0,f=1;
	char ch=getchar();
	while(ch<'0' || ch>'9')
	{
		if(ch=='-')
		{
			f=-1;
		}
		ch=getchar();
	}
	while(ch>='0' && ch<='9')
	{
		w=(w<<3)+(w<<1)+(ch^48);
		ch=getchar();
	}
	return w*f;
}

int n,ans;

struct thing
{
	int a;
	int b;
}t[maxn];

bool cmp(thing x,thing y)
{
	if(x.a!=y.a)
	{
		return x.a>y.a;
	}
	else
	{
		return x.b>y.b;
	}
}

int sum;

int main()
{
	n=read();
	
	for(int i=1;i<=n;i++)
	{
		t[i].a=read();
		t[i].b=read();
	}
	
	sort(t+1,t+n+1,cmp);
	
	ans+=t[1].b;
	
	sum+=t[1].a;
	
	for(int i=2;i<=n;i++)
	{
		if(t[i].b>0 && sum>0)
		{
			sum--;
			ans+=t[i].b;
			sum+=t[i].a;
		}
	}
	
	cout<<ans;
	
	return 0;
}

然后就WA声一片(不过这竟然能贪出60pts!!!)

emm....

01背包

仔细一看,这不就是个01背包么——代价为钩子,val为喜悦值

转移方程:dp[i][j]=max(dp[i-1][j],dp[i-1][max(j-t[i].a,0)+1]+t[i].b);

自信的交了上去

rnm劳资还不如贪心

然后就调了1h。。。。

然后就发现没开long long。。。

这告诉我们,能写贪心千万不要写正解(bushi

AC 代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<climits>
#include<algorithm>
#define int long long

using namespace std;

const int maxn=3010;

const int INF=-INT_MAX;

inline int read()
{
	int w=0,f=1;
	char ch=getchar();
	while(ch<'0' || ch>'9')
	{
		if(ch=='-')
		{
			f=-1;
		}
		ch=getchar();
	}
	while(ch>='0' && ch<='9')
	{
		w=(w<<3)+(w<<1)+(ch^48);
		ch=getchar();
	}
	return w*f;
}

int n;

int dp[maxn][maxn];

struct thing
{
	int a;
	int b;
}t[maxn];

bool cmp(thing x,thing y)
{
	return x.a>y.a;
}

signed main()
{
	n=read();
	
	for(int i=1;i<=n;i++)
	{
		t[i].a=read();
		t[i].b=read();
	}
	
	sort(t+1,t+n+1,cmp);
	
	for(int i=0;i<=n;i++)
	{
		dp[0][i]=INF;
		dp[i][n+1]=INF;
	}
	
	dp[0][1]=0;
	
	for(int i=1;i<=n;i++)
	{
		for(int j=0;j<=n;j++)
		{
			dp[i][j]=max(dp[i-1][j],dp[i-1][max(j-t[i].a,0ll)+1]+t[i].b);
		}
	}
	
	int ans=INF;
	
	for(int i=0;i<=n;i++)
	{
		ans=max(ans,dp[n][i]);
	}
	
	cout<<ans;
	
	return 0;
}

私たちはとても執着していて、そして思いが深ければ深いほど、絶望的になります。

posted @ 2022-09-20 15:39  NinT_W  阅读(31)  评论(0编辑  收藏  举报