BZOJ.4247.挂饰(背包DP)

题目链接

如果贪心,正的显然先选。然后处理负的,好像要用背包。
看这数据范围不如直接用背包。\(f[i][j]\)表示前\(i\)个物品,剩下\(j\)个钩子的最大价值。
因为没有钩子的放前面无法转移,所以先按\(A_i\)排序。

因为数据多 开N*N的数组在bzoj上跑的好慢。。

//1048kb    624ms
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
//#define gc() getchar()
#define MAXIN 200000
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
const int N=2005;

int f[2][N];
char IN[MAXIN],*SS=IN,*TT=IN;
struct Node
{
    int a,val;
    bool operator <(const Node &x)const
    {
        return a>x.a;
    }
}A[N];

inline int read()
{
    int now=0,f=1;register char c=gc();
    for(;!isdigit(c);c=='-'&&(f=-1),c=gc());
    for(;isdigit(c);now=now*10+c-'0',c=gc());
    return now*f;
}

int main()
{
    int n=read();
    for(int i=1; i<=n; ++i) A[i]=(Node){read(),read()};
    std::sort(A+1,A+1+n);
    memset(f,-0x3f,sizeof f);
    f[0][1]=0; int now=1,las=0;
    for(int i=1,s=1+A[i].a/*初始可以是1!(所有ai=0)*/; i<=n; s+=A[++i].a,las=now,now^=1)
        for(int j=0,a=A[i].a,v=A[i].val,l=std::min(n,s); j<=l; ++j)
            f[now][j]=std::max(f[las][j],f[las][std::max(j-a+1,1)]+v);
    int ans=0;
    for(int i=0; i<=n; ++i) ans=std::max(ans,f[las][i]);
    printf("%d\n",ans);

    return 0;
}

转载于:https://www.cnblogs.com/SovietPower/p/9675582.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值