http://codeforces.com/contest/366/problem/C

题意:给出n个水果的两种属性a属性和b属性,然后挑选苹果,选择的苹果必须要满足这样一个条件:,现在给出n,k,要你求满足这种条件的苹果a属性之和最大,如果找不到,输出-1.

思路:是dp题目,倒是给我提醒比较大。这个题目是可以转化的,转为  所有(aj-k*bj)之和,然后对于任意一个苹果,就是挑与不挑的关系,很明显的背包问题。

对于任意一个苹果,如果选择它,则是dp[v-(aj-k*bj)]+aj,不选择它,就是dp[j]自己本身.......额,好像很简单的样子,其实这样是错的。因为(aj-k*bj)可以是负数,那么这样转移就不对,因为有的状态数无法表示出来,比如说,当(aj-k*bj)==-5,那么对于dp[-1]这个状态可以从dp[4]转移过去,而实际上,dp[-1]是不合法的数组.....

如此来说,我想到的解决方法就是平移10000个单位,因为n,a[i],b[i]最大都是100,所以只需要平移10000个单位,当然为了不出现其他边界问题,我是平移了15000个单位,然后一遍背包过去,发现还是错的.......

回到题目所给出的公式,,转化过来,应该这样表述才是对的, 从(0——j)的(aj-k*bj)之和==0,实质上,转化为背包来做,这个题目的体积并没有固定,不是吗?但是从(0——j)的(aj-k*bj)之和==0这里却是给出了。若没有平移单位,那么最终值是dp[0]的值,这里平移了15000个单位,那么最终所求问题却应该是dp[15000],并且,是要将15000这个容量恰好装满,如此,似乎这道题目有解了,但是wa在第六组测试数据;

第一次wa代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int dp[40005];
int s[205][2];
int main()
{
int n,k;
while(scanf("%d%d",&n,&k)>0)
{
for(int i=1; i<=n; i++)
{
scanf("%d",&s[i][0]);
}
for(int i=1; i<=n; i++)
{
scanf("%d",&s[i][1]);
}
memset(dp,-1,sizeof(dp));
//for(int i=0;i<=n;i++)
//for(int j=0;j<=30000;j++)
//dp[j]=-(1<<31);
//printf("%d ",dp[i][j]);
int m=15000;
dp[m]=0;
for(int i=1; i<=n; i++)
{
int b=s[i][0]-k*s[i][1];
//printf("%d\n",b);
for(int j=2*m; j>=0; j--)
{
if(j-b>=0&&j-b<=2*m&&dp[j-b]!=-1)
{
if(dp[j-b]+s[i][0]>dp[j])
dp[j]=dp[j-b]+s[i][0];
} }
}
if(dp[m]==0)
printf("-1\n");
else
printf("%d\n",dp[m]);
}
return 0;
}

为什么会wa?想了很久,考虑到一个问题,对于dp[40000]这个数组,我只是将第一层置为-1,会不会在n层之后,会有这么一个现象,对于当前第n层,dp[j]!=-1,但实际上,dp[n][j]却是应该==-1的,也就是说,由于只是开了一维数组,我所需要的第n层数据被前面的值覆盖掉了.......这是很有可能的,出于小心,我把代码改为了二维数组,如下:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int dp[215][40005];
int s[205][2];
int main()
{
int n,k;
while(scanf("%d%d",&n,&k)>0)
{
for(int i=1; i<=n; i++)
{
scanf("%d",&s[i][0]);
}
for(int i=1; i<=n; i++)
{
scanf("%d",&s[i][1]);
}
memset(dp,-1,sizeof(dp));
//for(int i=0;i<=n;i++)
//for(int j=0;j<=30000;j++)
//dp[i][j]=-(1<<31);
//printf("%d ",dp[i][j]);
int m=15000;
dp[0][m]=0;
for(int i=1; i<=n; i++)
{
int b=s[i][0]-k*s[i][1];
//printf("%d\n",b);
for(int j=2*m; j>=0; j--)
{
if(j-b>=0&&j-b<=2*m&&dp[i-1][j-b]!=-1)
{
if(dp[i-1][j-b]+s[i][0]>dp[i-1][j])
dp[i][j]=dp[i-1][j-b]+s[i][0];
else
dp[i][j]=dp[i-1][j];
} }
}
int maxn=-10;
for(int i=0;i<=n;i++)
if(dp[i][m]>maxn)
maxn=dp[i][m];
if(maxn==0)
printf("-1\n");
else
printf("%d\n",maxn);
}
return 0;
}

额,继续wa在第六组测试数据......心中千万只草泥马飞奔而过......我思路没错啊,代码检查了好几次,好像也没什么问题......纠结许久,想着,会不会是我将所有值置为-1那里出现问题了?一般来说,要是恰好那么多容量的话,都是置为负无穷大,可是我用-1来标记负无穷大也没错啊,以前都是这样做的,没出什么问题......抱着试试的心态,改了下代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int dp[215][40005];
int s[205][2];
int main()
{
int n,k;
while(scanf("%d%d",&n,&k)>0)
{
for(int i=1; i<=n; i++)
{
scanf("%d",&s[i][0]);
}
for(int i=1; i<=n; i++)
{
scanf("%d",&s[i][1]);
}
//memset(dp,-1,sizeof(dp));
for(int i=0;i<=n;i++)
for(int j=0;j<=30000;j++)
dp[i][j]=-(1<<31);
//printf("%d ",dp[i][j]);
int m=15000;
dp[0][m]=0;
for(int i=1; i<=n; i++)
{
int b=s[i][0]-k*s[i][1];
//printf("%d\n",b);
for(int j=2*m; j>=0; j--)
{
if(j-b>=0&&j-b<=2*m)
{
if(dp[i-1][j-b]+s[i][0]>dp[i-1][j])
dp[i][j]=dp[i-1][j-b]+s[i][0];
else
dp[i][j]=dp[i-1][j];
} }
}
//int maxn=-10;
//for(int i=1;i<=n;i++)
//if(dp[i][m]>maxn)
//maxn=dp[i][m];
if(dp[n][m]==0)
printf("-1\n");
else
printf("%d\n",dp[n][m]);
}
return 0;
}

惊现ac..........可是,可是,我想的是这代码是不能ac的啊.....能不能靠谱点?决定了,以后对于这样要恰好的容积,都置为负无穷大。

但是我对于这代码想了许久,还是不知道为什么我把dp内所有值置为-1,会错......若有朋友路过,看到,请赐教.......,谢谢.......

cf 366C C. Dima and Salad(01背包)的更多相关文章

  1. CF#214 C. Dima and Salad 01背包变形

    C. Dima and Salad 题意 有n种水果,第i个水果有一个美味度ai和能量值bi,现在要选择部分水果做沙拉,假如此时选择了m个水果,要保证\(\frac{\sum_{i=1}^ma_i}{ ...

  2. CodeForces - 366C Dima and Salad (01背包)

    题意:n件东西,有属性a和属性b.要选取若干件东西,使得\(\frac{\sum a_j}{\sum b_j} = k\).在这个条件下,问\(\sum a_j\)最大是多少. 分析:可以将其转化为0 ...

  3. CF Dima and Salad 01背包

    C. Dima and Salad time limit per test 1 second memory limit per test 256 megabytes input standard in ...

  4. Codeforces 366C Dima and Salad:背包dp

    题目链接:http://codeforces.com/problemset/problem/366/C 题意: 有n个物品,每个物品有两个属性a[i]和b[i]. 给定k,让你选出一些物品,使得 ∑ ...

  5. Codeforces Round #214 (Div. 2) C. Dima and Salad (背包变形)

    C. Dima and Salad time limit per test 1 second memory limit per test 256 megabytes input standard in ...

  6. Dima and Salad(完全背包)

    Dima and Salad time limit per test 1 second memory limit per test 256 megabytes input standard input ...

  7. CodeForces-366C Dima and Salad 对01背包的理解 多个背包问题

    题目链接:https://cn.vjudge.net/problem/CodeForces-366C 题意 给出n个水果和一个常数k,其中每个水果都有两种性质ai, bi(美味度,卡路里量). 要保证 ...

  8. Codeforces Round #214 (Div. 2) C. Dima and Salad 背包

    C. Dima and Salad   Dima, Inna and Seryozha have gathered in a room. That's right, someone's got to ...

  9. codeforces-214(Div. 2)-C. Dima and Salad+DP恰好背包花费

    codeforces-214(Div. 2)-C. Dima and Salad 题意:有不同的沙拉,对应不同的颜值和卡路里,现在要求取出总颜值尽可能高的沙拉,同时要满足 解法:首先要把除法变成乘法, ...

随机推荐

  1. Java使用Itext5.5.10进行pdf签章

    说到PDF数字签名签章,这个其实也是数字证书信息安全的应用范畴,关于数字证书和数字签名,网上有很多解释说明,但讲解都多不够详细准确,这边推荐一篇大神的博文,讲解浅显易懂形象数字证书 数字签名 数据加密 ...

  2. C# WinForm给Button或其它控件添加快捷键响应

    今天做东西遇到要给按钮添加快捷键.就在这介绍三种添加快捷键的方式. 第一种Alt + *(按钮快捷键) 在大家给button.label.menuStrip等控件设置Text属性时在名字后边加& ...

  3. int和Integer之间的区别和联系

          在工作中使用==埋下的坑这篇博文中,我们看到当使用基本类型的时候==是完全没有问题的,部分或者混合使用基本类型和装箱基本类型的时候,就可能出现问题了,那么我们可能会想基本类型和装箱基本类型 ...

  4. Spring Cloud问题分析

    基于Spring Cloud框架开发时,经常会碰到各种开发问题,那么碰到这些问题时如何去解决呢?下面描述基于Spring Cloud问题定位的基本思路,大概可以分为如下几步: 排查配置问题 环境问题 ...

  5. Scala学习网址

    scala学习网址为:https://twitter.github.io/scala_school/zh_cn https://www.zhihu.com/question/26707124

  6. 解决Mac上adb: command not found问题

    使用mac进行开发的时候,有时候需要使用adb指令来进行一些操作,但是如果没有配置过Android环境变量,可能会出现adb: command not found的问题,查了一些资料,这里记录一下ma ...

  7. markdown中的锚点处理

    markdown markdown是一个相对简单的DSL,定义了简单的标签来描述html文档格式. 比如: #一级标题 来生成html <h1>一级标题<h1> ##二级标题 ...

  8. Maven 使用国内镜像

    1 修改maven 的配置文件 settings.xml,添加阿里云的一个中央仓库. 2 找到maven 的配置文件,一般在 maven 安装目录 apache-maven-3.5.0\conf 文件 ...

  9. 人民币金额转化汉字的java写法

    最近看到一个把一个浮点数转化为汉字人民币的小题,感觉很有意思就去用java实现了一下,没想到没有想得那么简单,在网上搜了一下也不近人意,经过几次修改后,现在实现了,现在分享一下. 一.当输入一个浮点数 ...

  10. springBoot bean注入

    1.@Component:把普通pojo实例化到spring容器中,相当于配置文件中的<bean id="" class=""/> 2.@Autow ...