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, 这么暴力的算 ...
随机推荐
- ReactNative环境配置
参考链接 Windows系统安装React Native环境 windows下React Native Android 环境搭建 在Windows下搭建React Native Android开发环境 ...
- C#的Attribute
using System; using System.Collections; using System.Collections.Generic; using System.IO; namespace ...
- 对Java内存模型即JMM的理解
类似物理上的计算机系统,Java虚拟机规范中也定义了一种Java内存模型,即Java Memory Model(JMM),来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能 ...
- repo 版本回退
转自:http://blog.csdn.net/wed110/article/details/52179386 1.repo 回退到具体某一天的提交 repo forall -c 'ID=`Git l ...
- Linux 配置NFS,文件共享
配置: 1.设定共享主机服务器 ---(注意防火墙) 编辑ipA端的/etc/exports 文件 [root@dbrac2 ~]# cat /etc/exports /media 192 ...
- HYSBZ 2440 完全平方数(莫比乌斯反演)
链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2440 若i为质数,n为i*i的倍数,则称n为含平方因子数. 求1~n的无平方因子数. F(x) ...
- WCF学习笔记之消息交换模式
在WCF通信中,有三种消息交换模式,OneWay(单向模式), Request/Reponse(请求回复模式), Duplex(双工通信模式)这三种通信方式.下面对这三种消息交换模式进行讲解. 1. ...
- RTP 与RTCP 解释. 含同步时间戳
转自:http://blog.csdn.net/wudebao5220150/article/details/13816225 RTP协议是real-time transport protocol的缩 ...
- 智能车学习(十七)——舵机学习
一.舵机的结构 舵机简单的说就是集成了直流电机.电机控制器和减速器等,并封装在一个便于安装的外壳里的伺服单元.能够利用简单的输入信号比较精确的转动给定角度的电机系统.舵机安装了一个电位器(或 ...
- 通信原理实践(二)——幅度调制
一.幅度调制,并画出时域和频域波形 1.代码如下: function [ p_n ] = AM_func( N,fs,fm,Am,fc,Ac,Ma ) %UNTITLED 此处显示有关此函数的摘要 % ...