luogu P4798 [CEOI2015 Day1]卡尔文球锦标赛 dp 数位dp
LINK:卡尔文球锦标赛
可以先思考一下合法的序列长什么样子.
可以发现后面的选手可以使用前面出现的编号也可以直接自己新建一个队.
其实有在任意时刻i 序列的mex>max.即要其前缀子序列中1~max的值都要出现过。
对于这种数排名的问题 容易想到是在某一位字典序小于要求的字典序 然后后面的随便放.
可以直接枚举这样的位置然后统计。最后可以统计出有多少个比当前要小的。
后续有一个 可以使用a 还有n个人这个样子的dp.总复杂度 \(n^3\) 期望得分50.
code
#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<ctime>
#include<cctype>
#include<queue>
#include<deque>
#include<stack>
#include<cstdlib>
#include<iomanip>
#include<algorithm>
#include<vector>
#include<list>
#include<bitset>
#include<utility>
#include<cmath>
#include<string>
#include<cstring>
#include<map>
#include<set>
#define mod 1000007
#define RE register
#define ll long long
#define putl(x) printf("%lld\n",x)
#define put(x) printf("%d\n",x)
#define put_(x) printf("%d ",x)
#define rep(p,n,i) for(int i=p;i<=n;++i)
#define fep(n,p,i) for(int i=n;i>=p;--i)
#define vep(p,n,i) for(int i=p;i<n;++i)
#define get(x) x=read()
using namespace std;
char *fs,*ft,buf[1<<15];
inline char gc()
{
return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
}
inline int read()
{
RE int x=0,f=1;RE char ch=gc();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=gc();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=gc();}
return x*f;
}
const int MAXN=10010;
int n;
int a[MAXN],f[MAXN],vis[MAXN];
int ans,cnt;
inline int add(int x,int y){return x+y>=mod?x+y-mod:x+y;}
inline int mul(int x,int y){return (ll)x*y%mod;}
inline int mus(int x,int y){return x-y<0?x-y+mod:x-y;}
inline int calc(int a,int n)
{
rep(1,cnt+n,i)f[i]=0;
f[cnt]=a;int ans=0;
rep(1,n,i)fep(cnt+n,cnt,j)f[j]=add(f[j-1],mul(j,f[j]));
rep(cnt,cnt+n,i)ans=add(ans,f[i]);return ans;
}
signed main()
{
//freopen("1.in","r",stdin);
get(n);int ans=0;
rep(1,n,i)get(a[i]);
rep(1,n,i)
{
if(a[i]>1)ans=add(ans,calc(a[i]-1,n-i));
if(!vis[a[i]])vis[a[i]]=1,++cnt;
}
put(ans+1);return 0;
}
考虑优化。
可以发现这个dp是无法进行优化了 插值还是矩阵乘法什么都不太行.
但是还是存在可以压缩的地方的 考虑两个位置 \(i,j\)dp到了第k位 尽管此时值不同但是可以用的数字是相同的 我们可以将其放在一起。
而且这也极像数位dp.
能用的数字的个数 更简单的方法为 最大值而不是上面代码中的cnt...
上面的压缩过程其实是把最大值相同的放在一起。
设\(f_{i,j,0/1}\)表示dp到了i这位的最大值为j是否存在最高位限制的方案数.
实际上 \(f_{i,j,1}\)这个可以直接省掉 因为可以的知在某一位的 有值且一定为1的只有一个地方。
转移不再赘述比较简单.
code
#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<ctime>
#include<cctype>
#include<queue>
#include<deque>
#include<stack>
#include<cstdlib>
#include<iomanip>
#include<algorithm>
#include<vector>
#include<list>
#include<bitset>
#include<utility>
#include<cmath>
#include<string>
#include<cstring>
#include<map>
#include<set>
#define mod 1000007
#define RE register
#define ll long long
#define putl(x) printf("%lld\n",x)
#define put(x) printf("%d\n",x)
#define put_(x) printf("%d ",x)
#define rep(p,n,i) for(int i=p;i<=n;++i)
#define fep(n,p,i) for(int i=n;i>=p;--i)
#define vep(p,n,i) for(int i=p;i<n;++i)
#define get(x) x=read()
using namespace std;
char *fs,*ft,buf[1<<15];
inline char gc()
{
return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
}
inline int read()
{
RE int x=0,f=1;RE char ch=gc();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=gc();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=gc();}
return x*f;
}
const int MAXN=10010;
int n,u;
int a[MAXN],b[MAXN];
int ans,cnt,mx;
int f[2][MAXN][2];
inline int add(int x,int y){return x+y>=mod?x+y-mod:x+y;}
inline int mul(int x,int y){return (ll)x*y%mod;}
inline int mus(int x,int y){return x-y<0?x-y+mod:x-y;}
int main()
{
//freopen("1.in","r",stdin);
get(n);get(a[1]);
if(n==1){puts("1");return 0;}
f[0][1][1]=1;
rep(2,n,i)
{
u^=1;get(a[i]);
fep(n,1,j)//枚举上一次的决策.
{
f[u][j][0]=f[u][j][1]=0;
if(f[u^1][j][0])
{
f[u][j][0]=add(f[u][j][0],mul(j,f[u^1][j][0]));
f[u][j+1][0]=add(f[u][j+1][0],f[u^1][j][0]);
}
if(f[u^1][j][1])
{
f[u][j][0]=add(f[u][j][0],mul(a[i]-1,f[u^1][j][1]));
if(a[i]==j+1)f[u][j+1][1]=add(f[u][j+1][1],f[u^1][j][1]);
else f[u][j][1]=add(f[u][j][1],f[u^1][j][1]);
}
}
}
rep(1,n,j)ans=add(ans,add(f[u][j][1],f[u][j][0]));
put(ans);return 0;
}
luogu P4798 [CEOI2015 Day1]卡尔文球锦标赛 dp 数位dp的更多相关文章
- [DP]数位DP总结
数位DP总结 By Wine93 2013.7 1.学习链接 [数位DP] Step by Step http://blog.csdn.net/dslovemz/article/details/ ...
- 数位dp模板 [dp][数位dp]
现在才想到要学数位dp,我是不是很弱 答案是肯定的 以一道自己瞎掰的题为模板 //题: //输入数字n //从0枚举到n,计算这n+1个数中含有两位数a的数的个数 //如12930含有两位数93 #i ...
- 【xsy1611】 数位dp 数位dp
这题是显然的数位$dp$,然而我居然写了一个下午!!! 我们不难想到差分,令$solve(x,y)$表示从第一个数字在区间$[0,x]$,第二个数字在区间$[0,y]$的答案. 不难发现题目中给了你一 ...
- Codeforces Round #235 (Div. 2) D. Roman and Numbers 状压dp+数位dp
题目链接: http://codeforces.com/problemset/problem/401/D D. Roman and Numbers time limit per test4 secon ...
- hdu4352-XHXJ's LIS状压DP+数位DP
(有任何问题欢迎留言或私聊 && 欢迎交流讨论哦 题意:传送门 原题目描述在最下面. 在区间内把整数看成一个阿拉伯数字的集合,此集合中最长严格上升子序列的长度为k的个数. 思路: ...
- luogu2657-Windy数题解--数位DP
题目链接 https://www.luogu.org/problemnew/show/P2657 分析 第一道数位DP题,发现有点意思 DP求\([L,R]\)区间内的XXX个数,很套路地想到前缀和, ...
- 浅谈数位DP
在了解数位dp之前,先来看一个问题: 例1.求a~b中不包含49的数的个数. 0 < a.b < 2*10^9 注意到n的数据范围非常大,暴力求解是不可能的,考虑dp,如果直接记录下数字, ...
- 数位dp 的简单入门
时间紧张,就不讲那么详细了. 之前一直被深搜代码误解,以为数位dp 其实就是记忆化深搜...(虽说爆搜确实很舒服而且还好想) 但是后来发现数位dp 的标准格式其实是 预处理 + dp ...... 数 ...
- 【距离GDOI:141天】 滚入数位DP的坑
作为博客园的第一篇...我都不知道要写什么了 ... 其实今天很没状态,就当吐槽吧... 嗯,被黄神带去写treap+可持久化线段树,然后在可持久化的删除上面跪了两天,真的是一跪不起.我已经连续多久没 ...
随机推荐
- 一起来看 HTML 5.2 中新的原生元素 <dialog>
不到一个月前,HTML 5.2 正式成为 W3C 的推荐标准(REC),其中,推出了一个新的原生模态对话框元素 <dialog>,乍一看,可能感觉它就是一个新增的元素,然而,作者最近在玩的 ...
- 移动端web app要使用rem实现自适应布局:font-size的响应式
关于webAPP的开发最主要解决的就是“自适应自适应布局”.常规的适配有很多做法,例如:流式布局.限死宽度等,但是这些方案都不是最佳的解决方法,而最满足设计需要的是: 元素可以根据屏幕大小而等比列变 ...
- 小程序被冻结,忘记原始ID,如何找回?
登录成功,提示被冻结,选择"账号找回": 阅读须知:账号类型选择“小程序”,需要输入小程序的原始ID,此时已经不记得了~~ 微信:搜索 “ 公众平台安全助手 ” 并关注 点击查 ...
- 深入Mybatis源码——执行流程
前言 上一篇分析Mybatis是如何加载解析XML文件的,本篇紧接上文,分析Mybatis的剩余两个阶段:代理封装和SQL执行. 正文 代理封装 Mybatis有两种方式调用Mapper接口: pri ...
- day09总结
with 上下文管理 # f = open(r"文件路径", mode="rt", encoding="utf-8")# data = f. ...
- LNMP架构应用案例----WordPress
一.环境部署 mysql 172.16.1.10 数据库 web01 10.0.0.11 172.1 ...
- node+express实现简单的增删改查
var express = require('express'); var bodyParser = require("body-parser"); var cors = requ ...
- python eval函数,将列表样式的字符串转化为列表
python eval函数,将列表样式的字符串转化为列表 >>> str_1 = '[1,2,3,4,5,6]'>>> type(str_1)<type 's ...
- Mysql基础(八):MySQL 表的一对一、一对多、多对多问题
将实体与实体的关系,反应到最终数据库表的设计上,将关系分为三种:一对一,一对多(多对一)和多对多,所有的关系都是表与表之间的关系; 一对一 一对一:一张表的一条记录只能与另外一条记录进行对应,反之亦然 ...
- python 面向对象专题(九):特殊方法 (二)__get__、__set__、__delete__ 描述符(二)覆盖型与非覆盖型描述符对比
前言 根据是否定义__set__ 方法,描述符可分为两大类. 实现 __set__ 方法的描述符属于覆盖型描述符,因为虽然描述符是类属性,但是实现 __set__ 方法的话,会覆盖对实例属性的赋值操作 ...