传送门:

  [1]:洛谷

  [2]:BZOJ

参考资料:

  [1]:追忆:往昔

题解

  上述参考资料的讲解清晰易懂,下面谈谈我的理解;

  关键语句:

  

  将此题转化为 "01背包" 类问题,关键就是上述语句;

  据此,定义 dp[ i ][ j ] 表示前 i 个物品在钩子剩余 j 个的状态下所获得的最大喜悦值;

  细节处理:

  

  为了应对负数的情况,让 dp[ i ][ j ] 的下标 j 全部增加 2000 ,这样就可以表示在负数范围内的值了。

  状态转移:

  首先,初始化 dp[][] 数组为 -INF,并令 dp[0][2001]=0(初始手机上含有一个挂钩);

 for(int i=;i <= n;++i)
{
a[i]--;
for(int j=;j <= ;++j)
{
dp[i][j]=max(dp[i][j],dp[i-][j]);
if(dp[i][j] == -INF)
continue; int k=min(j+a[i],);
dp[i][k]=max(dp[i][k],max(dp[i-][j]+b[i],dp[i-][k]));
}
}

  解释1:挂饰 i 可以提供 ai 个挂钩,但是,要把它挂到手机上需要消耗一个挂钩,所以,挂饰 i 额外提供 ai-1 个挂钩;

  解释2:第6行的更新是必不可少的,手动测试如下样例便可明白:


  解释3:第 11 行,dp[ i ][ k ] 只受状态 dp[ i-1 ][ j ] 和 dp[ i-1 ][ k ] 的影响,为什么在判断的时候需要额外与 dp[ i ][ k ] 判断呢?

       仔细看一下 k,如果 j+a[ i ] 超过上界 4000,那么 k = 4000,对于超过 4000 的肯定都更新到了 dp[ i ][ 4000 ]上;

       所以,dp[ i ][ 4000 ] 会首其他状态的影响,而不只是上述两种状态的影响;

  验证解释3的正确性:

  将第 11 行代码改成如下所示代码(AC):

 if(k < )
dp[i][k]=max(dp[i-][j]+b[i],dp[i-][k]);
else
dp[i][k]=max(dp[i][k],max(dp[i-][j]+b[i],dp[i-][k]));

  而改成如下所示代码(WA):

 dp[i][k]=max(dp[i-][j]+b[i],dp[i-][k]);

•Code

 #include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define mem(a,b) memset(a,b,sizeof(a))
const int maxn=2e3+; int n;
int a[maxn];
int b[maxn];
int dp[maxn][maxn<<]; int Solve()
{
for(int i=;i <= n;++i)
for(int j=;j <= ;++j)
dp[i][j]=-INF; dp[][]=;
for(int i=;i <= n;++i)
{
a[i]--;///物品i本身需要占用一个钩子,所以其可以提供的钩子个数为a[i]-1
for(int j=;j <= ;++j)
{
dp[i][j]=max(dp[i][j],dp[i-][j]); if(dp[i][j] == -INF)
continue; int k=min(j+a[i],);
dp[i][k]=max(dp[i][k],max(dp[i-][j]+b[i],dp[i-][k]));
}
}
int ans=;
for(int i=;i <= ;++i)
ans=max(ans,dp[n][i]);
return ans;
} int main()
{
// freopen("C:\\Users\\hyacinthLJP\\Desktop\\in&&out\\contest","r",stdin);
scanf("%d",&n);
for(int i=;i <= n;++i)
scanf("%d%d",a+i,b+i); printf("%d\n",Solve()); return ;
}

二维dp

•利用滚动数组降低dp的维数

  

•Code

 #include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define mem(a,b) memset(a,b,sizeof(a))
const int maxn=2e3+; int n;
int a[maxn],b[maxn];
int dp[maxn<<]; int Solve()
{
mem(dp,-INF);
dp[]=; for(int i=;i <= n;++i)
{
a[i]--;
if(a[i] > )
{
for(int j=;j >= ;--j)
{
if(dp[j] == -INF)
continue;
int k=min(j+a[i],);
dp[k]=max(dp[j]+b[i],dp[k]);
}
}
else
{
for(int j=;j <= ;++j)
{
if(dp[j] == -INF)
continue;
dp[j+a[i]]=max(dp[j]+b[i],dp[j+a[i]]);
}
}
}
int ans=;
for(int i=;i <= ;++i)
ans=max(ans,dp[i]); return ans;
}
int main()
{
scanf("%d",&n);
for(int i=;i <= n;++i)
scanf("%d%d",a+i,b+i); printf("%d\n",Solve()); return ;
}

一维dp(滚动数组)

JOISC2014 挂饰("01"背包)的更多相关文章

  1. BZOJ 4247 挂饰 01背包

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4247 JOI君有N个装在手机上的挂饰,编号为1...N. JOI君可以将其中的一些装在手机 ...

  2. P4138 [JOISC2014]挂饰

    P4138 [JOISC2014]挂饰 ◦          N个装在手机上的挂饰.挂饰附有可以挂其他挂件的挂钩.每个挂件要么直接挂在手机上,要么挂在其他挂件的挂钩上.直接挂在手机上的挂件最多有1个. ...

  3. [JOISC2014]挂饰

    嘟嘟嘟 这题其实还是比较好想的,就是有一个小坑点. 首先钩子多的排在前面,然后就是dp了. dp方程就是\(dp[i][j]\)表示到了第\(i\)建物品,还剩\(j\)个挂钩的最大喜悦值.转移就很显 ...

  4. 洛谷P4138 挂饰 背包

    正解:背包dp 解题报告: 昂先放链接qwq 感觉还挺妙的,,,真的我觉得我直接做可能是想不到背包的,,,我大概想不出是个背包的QAQ 但是知道是背包之后觉得,哦,好像长得也确实挺背包的吼,而且其实是 ...

  5. 【BZOJ4247】挂饰 背包

    [BZOJ4247]挂饰 Description JOI君有N个装在手机上的挂饰,编号为1...N. JOI君可以将其中的一些装在手机上. JOI君的挂饰有一些与众不同——其中的一些挂饰附有可以挂其他 ...

  6. 【bzoj4247】挂饰 背包dp

    题目描述 JOI君有N个装在手机上的挂饰,编号为1...N. JOI君可以将其中的一些装在手机上. JOI君的挂饰有一些与众不同——其中的一些挂饰附有可以挂其他挂件的挂钩.每个挂件要么直接挂在手机上, ...

  7. bzoj4247: 挂饰(背包)

    4247: 挂饰 题目:传送门 题解: 看完题目很明显的一道二维背包(一开始还推错了) 设f[i][j]表示前i个挂饰选完(可以有不选)之后还剩下j个挂钩的最大值(j最多贡献为n) 那么f[i][j] ...

  8. BZOJ 4247 挂饰 背包DP

    4247: 挂饰 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/problem.php?id ...

  9. bzoj4247: 挂饰(背包dp)

    4247: 挂饰 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1136  Solved: 454[Submit][Status][Discuss] ...

随机推荐

  1. vsync信号产生与分发

    以下分析基于android 4.4代码 vsync信号的产生.分发涉及到以下几个类,先主要了解下他们各自的功能: HWComposer:产生hardware vsync,post fb VSyncTh ...

  2. Sublime Text2的常用技巧总结(更新中...)

    1. 选中一段内容后,按 Tab 或者 shift Tab 可以控制缩进 2. alt + shift + 数字, 开启多个窗口,数字代表分割后的个数,分割后按 Ctrl + shift + 数字 可 ...

  3. Jeff Dean 光辉事迹

    这是Google 2007年的愚人节笑话,罗列了很多Jeff Dean的“光辉事迹”.大名鼎鼎的Jeff Dean想必不用我介绍了.……好吧,还是介绍一下,Jeff Dean是Google最早的一批员 ...

  4. 【JZOJ4858】【GDOI2017模拟11.4】Walk

    题目描述 在比特镇一共有n 个街区,编号依次为1 到n,它们之间通过若干条单向道路连接. 比特镇的交通系统极具特色,除了m 条单向道路之外,每个街区还有一个编码vali,不同街区可能拥有相同的编码.如 ...

  5. MUI - myStorage在ios safari无痕浏览模式下的解决方案

    myStorage在ios safari无痕浏览模式下的解决方案 今天看到了这个帖子LocalStorage 在 Private Browsing 下的一个限制, 吓尿了,如果用户开启了无痕浏览,ap ...

  6. ipad模拟器iPadian.exe

    http://dl.pconline.com.cn/download/368140.html 苹果IPAD模拟器!让你的电脑立刻拥有IOS系统!马上变成ipad!几百个免费的扩展应用程序,能登QQ,微 ...

  7. 自定义属性 —— data-*

    一.基本概念 在HTML5中添加了data-*的方式来自定义属性,所谓data-*实际上上就是data-前缀加上自定义的属性名,使用这样的结构可以进行数据存放.使用data-*可以解决自定义属性混乱无 ...

  8. 25-3 requests模块的cookie和代理操作

    一.基于requests模块的cookie操作 引言:有些时候,我们在使用爬虫程序去爬取一些用户相关信息的数据(爬取张三“人人网”个人主页数据)时,如果使用之前requests模块常规操作时,往往达不 ...

  9. 跳出手掌心--如何立即触发UIButton边界事件

    http://www.cocoachina.com/ios/20150611/12082.html 最近在使用UIButton的过程中遇到一个问题,我想要获得手指拖动button并离开button边界 ...

  10. 直击 KubeCon 现场 | 阿里云 Hands-on Workshop 亮点回顾

    相关文章链接[合集]规模化落地云原生,阿里云亮相 KubeCon China沉淀九年,一文看清阿里云原生大事件 2019 年 6 月 24 日至 26 日,KubeCon + CloudNativeC ...