D - Pearls

HDU - 1300

这个题目也是一个比较裸的斜率dp,依照之前可以推一下这个公式,这个很好推

这个注意题目已经按照价格升序排列序,所以还是前缀和还是单调的。

sum[i] 表示前面 i 种珍珠的花费的前缀和

dp[i]表示买前面 i 种珍珠需要的最少的花费

dp[i]=min(dp[j]+(sum[i]-sum[j]+10)*c[i]

j>k 如果要求选 j  更优,则需要满足下列式子

dp[j]+(sum[i]-sum[j]+10)*c[i]<dp[k]+(sum[i]-sum[j]+10)*c[i]

上面式子化简可得

dp[j]-dp[k]<c[i]*(sum[j]-sum[k])

令G[j,k]=(dp[j]-dp[k])/(sum[j]-sum[k])

如果G[j,k]<c[i]且j>k 则选 j 比选 k 更优

推出这个斜率的式子之后,然后要用它。

关键的来了:现在从左到右,还是设k<j<i,如果g[i,j]<g[j,k],那么j点便永远不可能成为最优解,可以直接将它踢出我们的最优解集。为什么呢?

分三种情况讨论

1  G[i,j]<G[j,k]<c[t] 那么 i 是比 j 更优的 所以可以排除 j 点

2 G[i,j]<c[t]<G[j,k]  那么 i 也是比 j 更优的,而且 k 比 j 也优 可以排除 j 点

3 c[t]<G[i,j]<G[j,k] 那么 k 是比 j 更优 可以排除 j 点

所以如果是G[i,j]<G[j,k] 且 i>j>k 那么就可以排除掉 j 这个情况,因为 j 两边永远可以找到一个比它更优的,这个也是一种优化

那如果 G[i,j]>G[j,k]     i>j>k 这种情况呢?

1 G[i,j]>G[j,k] >c[t] 那么 j  比 i 更优 k 比 j 更优

2 G[i,j]>c[t]>G[j,k] 那么 j 比 i 更优 j 也比 k 更优

3 c[t]>G[i,j]>G[j,k] 那么 i 比 j 更优 j 比 k 更优

这个就可以找到单调性了,

如果 i 从小往大 G[i,j] 越来越大,那么在 小于等于 c[t] 的范围内,情况也更优,

意思是 如果 i>j>k 如果可以在 j 点取得最优解,那么k点肯定可以排除,

所以就是找小于 c[t] 的最大的这个 j 。

如果是G[i,j]<Gj,k]&&i>j>k 这种情况可以找到一个 j 比两端都优的

因为这个题目c是单调递增的,所以可以用单调队列来维护。

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <string>
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
using namespace std;
const int maxn = 1e3 + ;
typedef long long ll;
ll dp[maxn], sum[maxn], c[maxn];
int que[maxn]; ll up(int i,int j)
{
return dp[i] - dp[j];
} ll down(int i,int j)
{
return sum[i] - sum[j];
} ll DP(int i,int j)
{
return dp[j] + (sum[i] - sum[j] + )*c[i];
} int main()
{
int t;
scanf("%d", &t);
while(t--)
{
int n;
scanf("%d", &n);
sum[] = dp[] = ;
for (int i = ; i <= n; i++) scanf("%lld%lld", &sum[i], &c[i]), sum[i] += sum[i - ];
int head = , tail = ;
que[tail++] = ;
for(int i=;i<=n;i++)
{
while (head + < tail&&up(que[head + ], que[head]) <= c[i] * down(que[head + ], que[head])) head++;//如果满足这个式子
//就是说明que[head+1]比 que[head]更优,所以可以删去这个que[head] 然后之后不满足这个式子了,说明que[head]比que[head+1]更优
//说明这个时候的队首就是最优的,就可以跳出循环
dp[i] = DP(i, que[head]);
while (head + < tail&&up(i, que[tail - ])*down(que[tail - ], que[tail - ]) <= up(que[tail - ], que[tail - ])*down(i, que[tail - ])) tail--;
que[tail++] = i;
}
printf("%lld\n", dp[n]);
}
return ;
}

D - Pearls HDU - 1300 斜率dp+二分的更多相关文章

  1. B - Lawrence HDU - 2829 斜率dp dp转移方程不好写

    B - Lawrence HDU - 2829 这个题目我觉得很难,难在这个dp方程不会写. 看了网上的题解,看了很久才理解这个dp转移方程 dp[i][j] 表示前面1~j 位并且以 j 结尾分成了 ...

  2. hdu2993之斜率dp+二分查找

    MAX Average Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  3. hdu 3507 斜率dp

    不好理解,先多做几个再看 此题是很基础的斜率DP的入门题. 题意很清楚,就是输出序列a[n],每连续输出的费用是连续输出的数字和的平方加上常数M 让我们求这个费用的最小值. 设dp[i]表示输出前i个 ...

  4. hdu 2829 斜率DP

    思路:dp[i][x]=dp[j][x-1]+val[i]-val[j]-sum[j]*sum[i]+sum[j]*sum[j]; 其中val[i]表示1~~i是一段的权值. 然后就是普通斜率dp做法 ...

  5. hdu 3586 树形dp+二分

    题目大意:给定n个敌方据点,1为司令部,其他点各有一条边相连构成一棵 树,每条边都有一个权值cost表示破坏这条边的费用,叶子节点为前线.现要切断前线和司令部的联系,每次切断边的费用不能超过上限lim ...

  6. HDU 3480 斜率dp

    Division Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 999999/400000 K (Java/Others)Total ...

  7. HDU - 1300 简单DP

    题意:买珠子的方案有两种,要么单独买,价钱为该种类数量+10乘上相应价格,要么多个种类的数量相加再+10乘上相应最高贵的价格买 坑点:排序会WA,喵喵喵? 为什么连续取就是dp的可行方案?我猜的.. ...

  8. hdu 2993 斜率dp

    思路:直接通过斜率优化进行求解. #include<iostream> #include<cstdio> #include<algorithm> #include& ...

  9. hdu 4258 斜率DP

    思路:dp[i]=dp[j]+(num[i]-num[j+1])^2; #include<iostream> #include<cstring> #include<alg ...

随机推荐

  1. 内存对齐 align

    /* 地址对齐:指的是存放数据的首地址%N==0,而且整个结构体的大小%M(结构体的有效对齐值)==0 1 数据类型的自身对齐值:char:1 short:2 int,flolat,double:4 ...

  2. Pandownload作者被抓之后

    近日,pandownload作者被抓,可以说是圈内的大事件,被抓之后, Pandownload 已经是打不开,用不了了 就在我为此感到惋惜的时候,竟然有出来个shengdownload 先来一块看看这 ...

  3. stand up meeting 12-10

    今天项目会议正好利用了大家上课前的十五分钟,大家对项目进度和项目中所遇到的问题进行了沟通. 由于天赋同学与重阳小组沟通及时有效,在mapping的过程中直接将单词本中的type与我们单词挑战中的que ...

  4. CodeForces - 913C (贪心)

    点完菜,他们发现好像觉得少了点什么? 想想马上就要回老家了某不愿透露姓名的林姓学长再次却陷入了沉思......... 他默默的去前台打算点几瓶二锅头. 他发现菜单上有n 种不同毫升的酒. 第 i 种有 ...

  5. [git] github 推送以及冲突的解决,以及一些命令

    推送以及冲突的解决:(我的觉得先看完) (正常情况就是把修改的文件 git add 然后git commit 然后推送就行啦): 下面是一些命令 1.查看分支状态(查看所有:当前检出分支的前面会有星号 ...

  6. 使用dynamic和MEF实现轻量级的AOP组件 (2)

    转摘 https://www.cnblogs.com/niceWk/archive/2010/07/21/1782092.html 偷梁换柱 上一篇我们初试了DynamicAspect这把小刀,如果你 ...

  7. 2020最新的web前端体系和路线图,想学web前端又不知道从哪开始的快来瞧一瞧呀

    web前端其实是相对于服务器语言是简单的,并且对于初学者是非常友好的,因为在前期学习能够看到很好的效果.但是他的路线 也就是学习体系不成熟,所以导致很多初学者不知道怎么学?下面我就讲讲web前端的体系 ...

  8. udp包最大数据长度是多少

    因为udp包头有2个byte用于记录包体长度. 2个byte可表示最大值为: 2^16-1=64K-1=65535    udp包头占8字节, ip包头占20字节, 65535-28 = 65507 ...

  9. Linux系统进入救援模式

    由于现在很多的服务器都是用的RedHat,CentOS也比较多,这里就介绍CentOS6.6的救援模式. 有很多人的linux在用的时候不小心修改了某个权限,导致系统启动不起来,下面我就来为大家解决一 ...

  10. java中interrupt,interrupted和isInterrupted的区别

    文章目录 isInterrupted interrupted interrupt java中interrupt,interrupted和isInterrupted的区别 前面的文章我们讲到了调用int ...