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条件注释_关于IE条件注释
普通的HTML注释形式是 <!-- 注释 --> 而IE5~IE9这5个版本的IE浏览器还另外支持一种特殊的if条件注释(感觉有点类似模板渲染时的语法结构) <!--[if IE]& ...
- MyBatis-Plus 用起来真的很舒服
一.MyBatis-Plus 1.简介 MyBatis-Plus 是一个 Mybatis 增强版工具,在 MyBatis 上扩充了其他功能没有改变其基本功能,为了简化开发提交效率而存在. 官网文档地址 ...
- day76 vue框架入门
目录 一.vue.js快速入门使用 1 vue.js库的下载 2 vue.js库的使用 3 vue.js的M-V-VM思想 4 显示数据 二.常用指令 1 操作属性 2 事件的绑定 3 样式操作 3. ...
- day51 表格与表单
目录 一.表格标签 二.表单标签 1 form内最重要的就是input标签,它通过type变形 2 select标签 3 textarea标签 4 重点 三.通过flask实现表单提交 四.css 1 ...
- (二)学习了解OrchardCore笔记——开篇:OrchardCore的中间件
现在开始看Starpup的中间件.这是一个扩展方法app.UseOrchardCore() public void Configure(IApplicationBuilder app, IHostEn ...
- Python并发编程05 /死锁现象、递归锁、信号量、GIL锁、计算密集型/IO密集型效率验证、进程池/线程池
Python并发编程05 /死锁现象.递归锁.信号量.GIL锁.计算密集型/IO密集型效率验证.进程池/线程池 目录 Python并发编程05 /死锁现象.递归锁.信号量.GIL锁.计算密集型/IO密 ...
- mysql练习题99
一.查询每个专业的学生人数 SELECT COUNT(*) FROM student GROUP BY majorid; 二.查询参加考试的学生中,每个学生的平均分.最高分 SELECT avg(sc ...
- 使用 maven 创建项目模板
前言 配置 demo 工程 生成模板 生成项目 上传模板到仓库 参看链接 前言 微服务的概念越来越流行,随着服务粒度越来越细,拆分的模块越来越明确,我们的工程项目也变得越来越多. 有时候一个项目搭建, ...
- Web Scraping using Python Scrapy_BS4 - using BeautifulSoup and Python
Use BeautifulSoup and Python to scrap a website Lib: urllib Parsing HTML Data Web scraping script fr ...
- Java冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序
冒泡排序 冒泡排序是一种简单的排序算法.它重复地走访过要排序地数列,一次比较两个元素,如果它们地顺序错误就把它们交换过来.走访数列地工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成. ...