HDU 2836 (离散化DP+区间优化)
Reference:http://www.cnblogs.com/wuyiqi/archive/2012/03/28/2420916.html
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2836
题目大意:计算序列有多少种组合,每个组合至少两个数,使得组合中相邻两个数之差不超过H,序列有重复的数。MOD 9901。
解题思路:
朴素O(n^2)
以样例1 3 7 5为例,如果没有重复的数。
设dp[i]前n个数的方案数,初始化为1。
那么for(1...i...N)
$dp[i]=\sum dp[j]+1\quad,where \quad \left |num[i]-num[j] \right|<=H$
+1是为了计算两个点直接连接的情况,如样例:
dp[1]=1 (无连接)
dp[2]=dp[1]+1=2 (1-3连接)
dp[3]=1 (无连接)
dp[4]=dp[2]+dp[3]+1=4(1-3-5, 3-5,7-5)
如果没有+1,那么就没法dp下去,同时,这样每个点多算了1,所以ans=1+2+1+4-4=4
快速求和优化
上面O(n^2)的原因在于, 原始序列的dp区间不是连续的,比如1,3,8,3,5,7 H=2
5的dp区间可以是2,4,需要多扫一轮来找出这些离散的值。
实际上,dp过程中可以不依赖原始序列顺序。将原始序列排序离散化去重后,变成1,3,5,8
这样,新添加一个box的时候,可以二分找其值在新序列中边界L,R,这样,原本的离散dp求和,
被转化成了连续区间求和$\sum sum(R)-sum(L-1)$
原因很简单,5在实际计算时,在3,3,7中都被牵扯到,是一个对称计算。所以排序去重后可以简化为对连续区间的计算。
至于为什么要去重,主要是为了解决重值的重复计算(原题并没有说没有重值)
比如1,3,3,如果不去重,为第二个3单独开个dp状态,那么1-3被算了两次(dp初始值为1)
所以第二个3,无须再开一个dp状态,直接第一个3基础上算就行了。保证ans-n是最后的结果。
代码
#include "cstdio"
#include "algorithm"
#include "cstring"
using namespace std;
#define maxn 100005
#define mod 9901
int num[maxn],Hash[maxn],n,h,s[maxn];
int lowbit(int x) {return x&(-x);}
int sum(int x)
{
int ret=;
while(x>) ret=(ret+s[x])%mod,x-=lowbit(x);
return ret%mod;
}
void update(int x,int d)
{
while(x<=n) s[x]=(s[x]+d)%mod,x+=lowbit(x);
}
int main()
{
//freopen("in.txt","r",stdin);
while(scanf("%d%d",&n,&h)!=EOF)
{
memset(Hash,,sizeof(Hash));
memset(s,,sizeof(s));
for(int i=;i<=n;i++)
{
scanf("%d",&num[i]);
Hash[i]=num[i];
}
sort(Hash+,Hash+n+);
int diff=unique(Hash+,Hash+n+)-Hash-;
int ans=;
for(int i=;i<=n;i++)
{
int idx=lower_bound(Hash+,Hash+diff+,num[i])-Hash;
int L=lower_bound(Hash+,Hash+diff+,num[i]-h)-Hash;
int R=upper_bound(Hash+,Hash+diff+,num[i]+h)-Hash-;
int dp=(sum(R)-sum(L-)+)%mod;
ans+=dp;
update(idx,dp);
}
printf("%d\n",(ans-n)%mod);
}
}
HDU 2836 (离散化DP+区间优化)的更多相关文章
- hdu 4833 离散化+dp ****
先离散化,然后逆着dp,求出每个点能取到的最大利益,然后看有没有钱,有钱就投 想法好复杂 #include <stdio.h> #include <string.h> #inc ...
- HDU 2829 [Lawrence] DP斜率优化
解题思路 首先肯定是考虑如何快速求出一段铁路的价值. \[ \sum_{i=1}^k \sum_{j=1, j\neq i}^kA[i]A[j]=(\sum_{i=1}^kA[i])^2-\sum_{ ...
- HDU 3480 Division DP斜率优化
解题思路 第一步显然是将原数组排序嘛--然后分成一些不相交的子集,这样显然最小.重点是怎么分. 首先,我们写出一个最暴力的\(DP\): 我们令$F[ i ][ j ] $ 为到第\(i\)位,分成\ ...
- HDU.2829.Lawrence(DP 斜率优化)
题目链接 \(Description\) 给定一个\(n\)个数的序列,最多将序列分为\(m+1\)段,每段的价值是这段中所有数两两相乘的和.求最小总价值. \(Solution\) 写到这突然懒得写 ...
- HDU3480_区间DP平行四边形优化
HDU3480_区间DP平行四边形优化 做到现在能一眼看出来是区间DP的问题了 也能够知道dp[i][j]表示前 i 个节点被分为 j 个区间所取得的最优值的情况 cost[i][j]表示从i ...
- HDOJ(HDU).2844 Coins (DP 多重背包+二进制优化)
HDOJ(HDU).2844 Coins (DP 多重背包+二进制优化) 题意分析 先把每种硬币按照二进制拆分好,然后做01背包即可.需要注意的是本题只需要求解可以凑出几种金钱的价格,而不需要输出种数 ...
- HDOJ(HDU).1059 Dividing(DP 多重背包+二进制优化)
HDOJ(HDU).1059 Dividing(DP 多重背包+二进制优化) 题意分析 给出一系列的石头的数量,然后问石头能否被平分成为价值相等的2份.首先可以确定的是如果石头的价值总和为奇数的话,那 ...
- HDU 3507 [Print Article]DP斜率优化
题目大意 给定一个长度为\(n(n \leqslant 500000)\)的数列,将其分割为连续的若干份,使得 $ \sum ((\sum_{i=j}^kC_i) +M) $ 最小.其中\(C_i\) ...
- R - Weak Pair HDU - 5877 离散化+权值线段树+dfs序 区间种类数
R - Weak Pair HDU - 5877 离散化+权值线段树 这个题目的初步想法,首先用dfs序建一颗树,然后判断对于每一个节点进行遍历,判断他的子节点和他相乘是不是小于等于k, 这么暴力的算 ...
随机推荐
- grep -v 排除多人字符串
# egrep -v '^$|^#' /etc/httpd/conf/httpd.conf # grep -v '^$\|^#' /etc/httpd/conf/httpd.conf
- volatile关键字与线程间通信
>>Java内存模型 现在计算机普遍使用多处理器进行运算,并且为了解决计算机存储设备和处理器的运算速度之间巨大的差距,引入了高速缓存作为缓冲,缓存虽然能极大的提高性能,但是随之带来的缓存一 ...
- settimeout,cleartimeout的使用分析
设置时间的定时轮回执行,大家想到的js也就是settimeout这个方法,这个方法确实能够实现定时反复执行的功能,clearttimeout这是清理或者是暂停轮回执行的情况.可是发现clearttim ...
- 【翻译七】java-同步
Synchronization Threads communicate primarily by sharing access to fields and the objects reference ...
- 【JAVA IO流之字符流】
一.概述. java对数据的操作是通过流的方式.java用于操作流的对象都在IO包中.流按照操作数据不同分为两种,字节流和字符流.流按照流向分为输入流,输出流. 输入输出的“入”和“出”是相当于内存来 ...
- 如何观察JS的事件队列的执行划分
也就是说,不同的操作函数,操作符,JS将其放入事件队列是不一样的... 比如: 外部函数和内部函数,就是分两次放入事件循环的尾端的. 比如,多个操作符组成的链式操作,也有可能是放不同的操作批次进入事件 ...
- poj 1006:Biorhythms(水题,经典题,中国剩余定理)
Biorhythms Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 110991 Accepted: 34541 Des ...
- PHP面向对象编程之深入理解方法重载与方法覆盖(多态)
这篇文章主要介绍了PHP面向对象编程之深入理解方法重载与方法覆盖(多态)的相关资料,需要的朋友可以参考下: 什么是多态? 多态(Polymorphism)按字面的意思就是"多种状态" ...
- PowerDesigner连接Oracle数据库生成数据模型【数据源连接方式】
1.进入操作系统的管理工具 2.选择ODBC数据源[32位或64位] 3.列表中是当前数据库已有的数据源,右侧点击添加按钮,添加适合自己的数据源 4.在列表中选择索要连接数据库的ODBC驱动[这里我要 ...
- jquery mobile 转场闪屏的解决
jqm转场闪屏是用phonegap生成apk非常容易遇到的问题,暂时貌似还是没有完美的解决方案,网上暂时有一些方案,个人都尝试了一下发现还是改背景比较有效,总结如下: 改变默认css文件: .ui- ...