【BZOJ4584】[Apio2016]赛艇

Description

在首尔城中,汉江横贯东西。在汉江的北岸,从西向东星星点点地分布着个划艇学校,编号依次为到。每个学校都拥有若干艘划艇。同一所学校的所有划艇颜色相同,不同的学校的划艇颜色互不相同。颜色相同的划艇被认为是一样的。每个学校可以选择派出一些划艇参加节日的庆典,也可以选择不派出任何划艇参加。如果编号为的学校选择派出划艇参加庆典,那么,派出的划艇数量可以在Ai至Bi之间任意选择(Ai<=Bi)。值得注意的是,编号为i的学校如果选择派出划艇参加庆典,那么它派出的划艇数量必须大于任意一所编号小于它的学校派出的划艇数量。输入所有学校的Ai、Bi的值,求出参加庆典的划艇有多少种可能的情况,必须有至少一艘划艇参加庆典。两种情况不同当且仅当有参加庆典的某种颜色的划艇数量不同

Input

第一行包括一个整数N,表示学校的数量。接下来N行,每行包括两个正整数,用来描述一所学校。其中第行包括的两个正整数分别表示Ai,Bi(1<=Ai<=Bi<=10^9),N<=500

Output

输出一行,一个整数,表示所有可能的派出划艇的方案数除以1,000,000,007得到的余数

Sample Input

2
1 2
2 3

Sample Output

7

题解:一开始设的是二维状态,显然不可做啊。。。

先离散化得到2*n个区间,然后用f[i][j][k]表示前i个学校,最后一个学校的数量在第j个区间中,并且第j个区间中已经有k个数的方案数。

如果上一个学校与当前学校不再同一个区间,那么我们维护s[j]表示$\sum\limits_{l<j}f[i][l][..]$,那么直接用s更新f即可。如果上一个学校与当前学校在同一个区间,那么这个区间中的方案数显然是一个组合数,维护一下组合数就好了。

如果采用01背包式的枚举顺序,在空间上可以省掉一维。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const ll P=1000000007;
int n,m;
ll ans;
int A[510],B[510],siz[1010];
ll ref[1010],f[1010][510],s[1010],ine[510];
struct node
{
int val,org;
}num[1010];
bool cmp(node a,node b)
{
return a.val<b.val;
}
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-') f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
int main()
{
n=rd();
int i,j,k;
for(i=1;i<=n;i++) num[i].val=rd()-1,num[i].org=i,num[i+n].val=rd(),num[i+n].org=i;
sort(num+1,num+2*n+1,cmp);
for(i=1;i<=2*n;i++)
{
if(i==1||num[i].val>num[i-1].val) ref[++m]=num[i].val;
if(!A[num[i].org]) A[num[i].org]=m+1;
else B[num[i].org]=m;
}
ine[1]=1;
for(i=2;i<=n;i++) ine[i]=P-(P/i)*ine[P%i]%P;
for(i=1;i<=n;i++)
{
for(s[0]=1,j=1;j<=B[i];j++)
{
s[j]=s[j-1];
for(k=1;k<=siz[j];k++) s[j]=(s[j]+f[j][k])%P;
}
for(j=B[i];j>=A[i];j--)
{
siz[j]=min(ref[j]-ref[j-1],siz[j]+1ll);
for(k=siz[j];k>=2;k--) f[j][k]=(f[j][k]+f[j][k-1]*(ref[j]-ref[j-1]-k+1)%P*ine[k])%P;
f[j][1]=(f[j][1]+s[j-1]*(ref[j]-ref[j-1]))%P;
}
}
for(i=1;i<=m;i++) for(j=1;j<=siz[i];j++) ans=(ans+f[i][j])%P;
printf("%lld",ans);
return 0;
}

【BZOJ4584】[Apio2016]赛艇 DP的更多相关文章

  1. BZOJ4584 APIO2016赛艇(动态规划+组合数学)

    如果值域不大,容易想到设f[i][j]为第i个学校选了j的方案数,枚举上一个学校是哪个选了啥即可,可以前缀和优化.于是考虑离散化,由于离散化后相同的数可能可以取不同的值,所以枚举第一个和其所选数(离散 ...

  2. BZOJ4584 : [Apio2016]赛艇

    首先将值域离散化成$O(n)$个连续段. 设$f[i][j][k]$表示第$i$个学校派出的数量在第$j$个连续段,在第$j$个连续段一共有$k$个学校的方案数.用组合数以及前缀和转移即可. 时间复杂 ...

  3. BZOJ 4584 luogu P3643: [Apio2016]赛艇

    4584: [Apio2016]赛艇 Time Limit: 70 Sec  Memory Limit: 256 MB[Submit][Status][Discuss] Description 在首尔 ...

  4. bzoj 4584: [Apio2016]赛艇【dp】

    参考:https://www.cnblogs.com/lcf-2000/p/6809085.html 设f[i][j][k]为第i个学校派出的赛艇数量在区间j内,并且区间j内共有k个学校的方案数 把数 ...

  5. APIO2016赛艇

    首先每个学校的边界范围是\(1e9\),肯定不能直接\(dp[i][j]\)表示前i所学校,第\(i\)所学校派出\(j\)艘船,但\(b<=500\)所有考虑把\(a,b\)离散,第二维改为当 ...

  6. BZOJ 4584 [Apio2016]赛艇 ——动态规划

    Subtask 1 直接$N^2$ $DP$,就可以了 Subtask 2 用$f[i][j]$表示当前位置为$i$,结束元素为$j$的方案数. Subtask 3 看下面 Subtask 4 首先可 ...

  7. 校际联合Contest

    每次开一个坑都像是重新被碾压的预感 最近的新闻,以前很喜欢乔任梁的<复活>...然后他就死了...感觉我再多愁善感一点的话...就要悲伤逆流成河了吧... Contest 09/24(乐滋 ...

  8. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  9. 2017FJ省队集训 游记

    2017FJ省队集训 游记 又是一篇流水账 Day 1 今天是省队集训的第一天.早上骑车去八中,到的时候汗流太多浑身湿透被杨哥哥和runzhe2000 d了,一个说我去游泳了一个说我打球了...流完汗 ...

随机推荐

  1. SQL SERVER 如何处理带字母的自增列--【叶子】

    --需求说明: /* id         col ---------- ---------- AB00001    a AB00002    b --当再插入数据的时候让id自动变成AB00003 ...

  2. 【转】可在广域网部署运行的即时通讯系统 -- GGTalk总览(附源码下载)

    原文地址:http://www.cnblogs.com/justnow/p/3382160.html (最新版本:V6.0,2017.12.11 .即将推出Xamarin移动端版本,包括 Androi ...

  3. 兼容placeholder

    众所周知.IE9以下不兼容placeholder属性,因此自己定义了一个jQuery插件placeHolder.js.以下为placeHolder.js的代码: /** * 该控件兼容IE9下面,专门 ...

  4. unity调用系统剪切板功能

    package com.game.utils; import android.app.Activity; import android.content.ClipData; import android ...

  5. Atitit.软件开发的几大规则,法则,与原则。。。attilax总结

    Atitit.软件开发的几大规则,法则,与原则... 1. 设计模式六大原则 2 1.1. 设计模式六大原则(1):单一职责原则 2 1.2. 设计模式六大原则(2):里氏替换原则 2 1.3. 设计 ...

  6. PHPCMS 后台学习

    1.final 不能被子类改写,不可扩展2.私有不能被继承3.构造方法,第一个被调用的方法4.static访问 类名::方法名 parent::test();这里test可以不静态 m=模块名& ...

  7. JAVA设计模式之 命令模式【Command Pattern】

    一.概述 命令模式能够将请求发送者和接收者全然解耦.发送者与接收者之间没有直接引用关系,发送请求的对象仅仅须要知道怎样发送请求,而不必知道怎样完毕请求.核心在于引入了命令类,通过命令类来减少发送者和接 ...

  8. Binary Tree Postorder Traversal --leetcode

    原题链接:https://oj.leetcode.com/problems/binary-tree-postorder-traversal/ 题目大意:后序遍历二叉树 解题思路:后序遍历二叉树的步骤: ...

  9. 170. Rotate List【medium】

    Given a list, rotate the list to the right by k places, where k is non-negative.   Example Given 1-& ...

  10. 【Objective-C】03-第一个OC程序

    一.打开Xcode,新建Xcode项目 二.选择最简单的命令行项目 因为我们只是学习OC语法,还未正式进入iOS开发,所以选择命令行项目即可 三.输入项目名称,选择Foundation框架进行创建项目 ...