最优卡组

最优卡组

参考:【LOJ6254】最优卡组

题解

我们可以先考虑堆模拟搜索。可以先将卡包内部排序,再用卡包的最大与次大排序。

我们用一个四元组(val,x,y,z)存储状态,val即当前的卡能量值,选择前x包卡,第x包选的是第y张牌。z表示是否它由下方的第2,3情况转来。

有如下几种情况:

1.当y< c_{x},则我们可选的情况有\left ( val+...,x,y+1,0 \right )

2.当x< n,则我们可选的情况有\left ( val+...,x+1,2,1 \right )

3.当x< n,z= 1,则我们可选的情况有\left ( val+...,x+1,2,1 \right )

可以证明这样枚举不会重复或漏掉。可惜我不会

源码

#include
#include
#include
#include 
#include
#include
#include
#include
#include
#define node ming
using namespace std;
typedef long long LL;
const LL INF=0x3f3f3f3f;
const LL MAXN=3000010;
template
char nc()
{
    static char buf[100000],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
LL rd()
{
    LL ret=0;
	char gc=getchar();
    while(!isdigit(gc)) gc=getchar();
    while(isdigit(gc))  ret=ret*10+(gc^'0'),gc=getchar();
    return ret;
}
struct ming
{
	LL val;
	int x,y;
	bool z;
	ming(){}
	ming(LL V,int X,int Y,bool Z){val=V;x=X;y=Y;z=Z;}
	bool operator < (const ming &a)const
	{
		return val q;
int n,m;
int p[MAXN],c[MAXN];
vector v[MAXN];
bool cmp1(const int &a,const int &b)
{
	return a>b;
}
bool cmp2(const int &a,const int &b)
{
	if(c[a]==1||c[b]==1) return c[a]!=1;
	return  v[a][0]-v[a][1]

谢谢!!!

你可能感兴趣的:(------贪心------)