补充一下我理解的中文题意。。

你要重新组装电脑。。电脑有一些部件。。
你的预算有b,b(1~1e9),有n个部件。。
每个部件有类型和名称以及价钱和质量
现在你要在不超过预算b的情况下。。
每个类型都买一个部件。。然后最终的质量由最小的质量决定
在此约束下问你在预算b之内能组装的最大的质量是多少
对每个部件价钱范围1e6,质量范围1e9

===============

由于钱和质量没有必然联系

所以我们不能直接从质量小的开始贪。。

也没法从质量大的开始贪吧。。因为你还要保证你的钱要够

按质量排序则钱是无序的。。这样反正不好处理。。其他的处理方法我还没有想到

所以说你要怎么搞呢。。

a1,b1,a2,b2,a3,b3

c1,d1,c2,d2,c3,d3

x1,y1,x2,y2,x3,y3

因为一旦你的钱固定的话。。对于每一个枚举的总钱数。。这里的钱数是固定的。。

也就是dp中离散的钱数。。每一个枚举的钱数状态来说。。钱是固定的。。

所以你第一种取不取。。会对后面造成影响。。因为总钱数少了。。

好像也不是太好dp,如果算前i种物品剩余钱数是j所能达到的最大的最小质量

我后来想算前i种物品能够达到质量q的最小钱数。。但是由于q很大不能离散。。所以不能dp?这个理由好像很牵强。。

我现在也不是太清楚离散化和dp之间是什么关系。。但是毫无疑问对于一些连续的问题dp解决不了

一种解法是说。。我们二分最后的质量q。。

之前我在纠结

如果大于等于q1的最便宜的所有零件的组合超过预算。。

大于等于q2(q2>q1)的最便宜的所有零件的组合却不超过预算
但是这是不存在的。。q单调增加时。。最便宜的价格也单调递增。。

 价格虽然无序。。但随着有序性质质量的单调递增。。最小价格单调递增。。
我大概是表达这个意思。。 
因为如果质量小,这意味着你的选择性更多(比质量大的),所以也就最小价格也就可能越小
所以我们来二分一下最小质量。。因为每次都取最便宜的部件。。所以说。。其总价格也是单调递增的,前面证过了。。
所以对于每次二分的结果。。对每种部件取大于等于这个结果的最便宜的部件。。最后check超不超过预算
超过就质量往左走。。不超过就往右走。。,最后就能求出大于等于q的最小预算 ,最后就能求出来大于等于q的最小预算在不超过总预算的
情况下所能达到的最大的q
 

 

按理说我的下标只能到2..因为一共3个元素。。

但是。。下标3,4却能访问。。不报越界。。其值是一个野值吧。。

这一点我们以后一定要注意。。

但是你如果程序一开始你就访问4.。就会停止运行。。

这个vector的trick一定要记好了。。

#include <iostream>
#include <cstdio>
#include <map>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
int n,b,cnt;
char op1[50];char op2[50];
struct node{int x,q;node(int x,int q):x(x),q(q){}};
typedef long long ll;
const int maxn=1e3+7;
vector<node> things[maxn];
int mxcheap[maxn][maxn];
bool cmp(node a,node b){return (a.q!=b.q)?a.q<b.q:a.x<b.x;}
void init(){int i;for(i=0;i<maxn;++i) things[i].clear();}
void Sort(){int i;for(i=0;i<cnt;++i) sort(things[i].begin(),things[i].end(),cmp);}
bool check(int key){int i;ll sum=0;
for(i=0;i<cnt;++i){
int left=0,right=things[i].size()-1,mid;
while(left<=right){
mid=(left+right)>>1;
if(things[i][mid].q<key) left=mid+1;else right=mid-1;
}
if(right+1<things[i].size()&&things[i][right+1].q>=key) right++;
if(left>things[i].size()-1) {
return false;}
sum+=mxcheap[i][right];
}
return (sum>b)?false:true;}
int main(){ int t;scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&b);init();
int i,j,x,q,lq=-1,rq=-1;cnt=0;
map<string,int> mp;
for(i=0;i<n;++i){
scanf("%s%s%d%d",op1,op2,&x,&q);
if(!mp.count(string(op1))){
mp[string(op1)]=cnt++;
}
things[mp[string(op1)]].push_back(node(x,q));
rq=(rq==-1)?q:max(q,rq);
lq=(lq==-1)?q:min(q,lq);
}
Sort();
for(i=0;i<cnt;++i){
mxcheap[i][things[i].size()-1]=things[i].back().x;
for(j=things[i].size()-2;j>=0;--j){
mxcheap[i][j]=min(things[i][j].x,mxcheap[i][j+1]);
}
}
int left=lq,right=rq,mid,ans=-1;
while(left<=right){
mid=(left+right)>>1;
if(check(mid)){left=mid+1;}
else{right=mid-1;}
}
if(check(right+1)) right++;
printf("%d\n",right);
}
return 0;
}

这里我犯了一个错。。那就是。。check中的二分写错了。。

即使写对了也不对。。因为。。我以为质量最接近q的价格最便宜。。这只是对所有等于q的东西来说。。

那么对于大于q的可能更加便宜。。所以我们这里需要预处理出每种部件的i~size的区间的最小值。。

二分得到边界即可。。但是对于二分来讲。。我们应当既考虑left>size-1(size是vector的size)

也要考虑left<0,比如要求第一个》=q的元素的下标。。这里如果全部大于key那么right会小于0,

你要判断right+1合不合法以免漏判,如果全部小于key那么right=size-1,而left=size,此时left

就越界了。。这是妥妥的无解。。一定要注意这一点

性质:任何无序序列的区间i~n的最值都是单调的

hdu2333-贪心,如何去后效性,背包太大怎么办,如何最大化最小值,从无序序列中发掘有序性质的更多相关文章

  1. 概率+后效性处理——cf930B好题

    之前题目看错了.. 先用双倍字符串处理后效性 首先要确定一个结论:如果原串s中相距为d的ch1和ch2只有一对,那么如果第一个翻开ch1,第二个翻开ch2,就能确定k 现在要求的是当我们第一次翻开的是 ...

  2. hadoop日志太大

    hadoop jobtracker日志太大在jobtracker服务器上的mapred-site.xml中添加以下参数: <property> <name>mapreduce. ...

  3. markdown 插入图片太大?怎么设定图片大小?

    你一定在插入图片的时候,遇到图片太大,影响观感的问题. Markdown中,图片大小的设定方式有两种 第一种: ![](https://img2018.cnblogs.com/blog/1735896 ...

  4. BZOJ3875--骑士游戏(SPFA处理带后效性的动态规划)

    3875: [Ahoi2014]骑士游戏 Time Limit: 30 Sec  Memory Limit: 256 MBSubmit: 181  Solved: 91[Submit][Status] ...

  5. luogu 4042 有后效性的dp

    存在有后效性的dp,但转移方程 f[i] = min( f[i], s[i] + sigma f[j] ( j 是后效点) ) 每次建当前点和 转移点的边 e1, 某点和其会影响的点 e2 spfa ...

  6. Educational Codeforces Round 62 E 局部dp + 定义状态取消后效性

    https://codeforces.com/contest/1140/problem/E 局部dp + 定义状态取消后效性 题意 给你一个某些位置可以改变的字符串,假如字符串存在回文子串,那么这个字 ...

  7. Codeforces - 24D 有后效性的DP处理

    题意:在n*m的网格中,某个物体初始置于点(x,y),每一步行动都会等概率地停留在原地/往左/往右/往下走,求走到最后一行的的步数的数学期望,其中n,m<1000 lyd告诉我们这种题目要倒推处 ...

  8. Luogu P2973 [USACO10HOL]赶小猪Driving Out the Piggi 后效性DP

    有后效性的DP:$f[u]$表示到$u$的期望次数,$f[u]=\Sigma_{(u,v)} (1-\frac{p}{q})*f[v]*deg[v]$,最后答案就是$f[u]*p/q$ 刚开始$f[1 ...

  9. CF24D Broken robot 后效性DP

    这题咕了好久..... 设$f[i][j]$表示从$(i,j)$到最后一行的期望步数: 则有 $ f[i][1]=\frac{1}{3}(f[i][1]+f[i][2]+f[i+1][1])+1$ $ ...

随机推荐

  1. Eureka详解系列(二)--如何使用Eureka(原生API,无Spring)

    简介 通过上一篇博客 Eureka详解系列(一)--先谈谈负载均衡器 ,我们知道了 Eureka 是什么以及为什么要使用它,今天,我们开始研究如何使用 Eureka. 在此之前,先说明一点.网上几乎所 ...

  2. Failed to start LSB: starts php-fpm

    跟nginx一样都是进程占用,记录下 [root@localhost pazzn]# systemctl status php-fpm.service ● php-fpm-72.service - L ...

  3. 在vCenter Server中添加ESXi 主机失败的问题

    报错:出现了常规系统错误: Timed out waiting for vpxa to start 报错是这个,我看了下vcenter的版本是6.5,如图右上,这个报错是因为我ESXI主机是6.7的, ...

  4. Redis持久化之RDB和AOF

    Redis是一个键值对数据库服务器,由于Redis是内存数据库,那么有很多内存的特点,例如掉电易失,或者进程退出,服务器中的数据也将消失不见,所以需要一种方法将数据从内存中写到磁盘,这一过程称之为数据 ...

  5. (转载)微软数据挖掘算法:Microsoft 关联规则分析算法(7)

    前言 本篇继续我们的微软挖掘算法系列总结,前几篇我们分别介绍了:微软数据挖掘算法:Microsoft 决策树分析算法(1).微软数据挖掘算法:Microsoft 聚类分析算法(2).微软数据挖掘算法: ...

  6. 从零开始学Java (二)Hello

    1.新建Hello.java文件,写入以下内容 1 public class Hello { 2 public static void main(String[] args) { 3 System.o ...

  7. three.js cannon.js物理引擎之制作拥有物理特性的汽车

    今天郭先生说一说使用cannon.js的车辆辅助类让我们的汽车模型拥有物理特性.效果图如下,在线案例请点击博客原文. 下面我们说一下今天要使用的两个类,并简单的看看他们的物理意义 1. Raycast ...

  8. 向指定url发送Get/Post请求

    向指定url发送Get/Post请求 1.向指定url发送Get/Post请求 2.HttpUtil 工具类–向指定url发送Get/Post请求 1.向指定url发送Get/Post请求 impor ...

  9. Spring MVC—数据绑定机制,数据转换,数据格式化配置,数据校验

    Spring MVC数据绑定机制 数据转换 Spring MVC处理JSON 数据格式化配置使用 数据校验 数据校验 Spring MVC数据绑定机制 Spring MVC解析JSON格式的数据: 步 ...

  10. Jenkins ( jenkins+harbor)

    Harbor 是咱们国产的docke仓库具体详细了解请参考以下连接 https://blog.csdn.net/csdn_duomaomao/article/details/78036331 http ...