51nod1370 排列与操作
性质:最终值域相同的一定是连续一段
花费最小?一定是值域个数个!并且当最后为i的数恰好只有i一个位置的时候,肯定选择不动,少花费一个
所以,我们考虑:每个最终方案在花费最小的方案下恰好被统计一次!
而对于一个合法的最终序列,考虑是怎样构造的
一定是先构造小的数,填充一些区间,再用大的数,可能覆盖一些小数的区间
换句话说,只要每个数的能填充这一段区间,就是合法的
也就是这个区间不能存在比这个数大的数!
有了这个发现,DP状态和转移就容易设计了
连续一段好处理,但是怎么知道之前没有出现过这个数?
还和位置有关,所以考虑顺序DP,到了i位置,考虑a[i]在最终序列的出现情况
f[i][j][k]考虑完了前i个位置,最终序列确定了前j个,花费k次
1.f[i-1][i-1][k]->f[i][i][k]i单独一块,不花费
2.f[i-1][j'][k-1]->f[i][j][k]把[j'+1,j]都变成a[i],前提是[j'+1,j]没有比a[i]大的,可以提前找到[l,r]极大的区间都<=a[i]
特别地,当j=i的时候,j'<j-1,否则白白花费一个代价,不满足“每个最终方案在花费最小的方案下恰好被统计一次!”,我们在第一个转移考虑了,这样会算重
3.f[i-1][j][k]->f[i][j][k],a[i]这个数不会出现在值域集合内。直接覆盖
第2个用前缀和优化即可
#include<bits/stdc++.h>
#define reg register int
#define il inline
#define fi first
#define se second
#define mk(a,b) make_pair(a,b)
#define numb (ch^'0')
#define pb push_back
#define solid const auto &
#define enter cout<<endl
#define pii pair<int,int>
using namespace std;
typedef long long ll;
template<class T>il void rd(T &x){
char ch;x=;bool fl=false;
while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
for(x=numb;isdigit(ch=getchar());x=x*+numb);
(fl==true)&&(x=-x);
}
template<class T>il void output(T x){if(x/)output(x/);putchar(x%+'');}
template<class T>il void ot(T x){if(x<) putchar('-'),x=-x;output(x);putchar(' ');}
template<class T>il void prt(T a[],int st,int nd){for(reg i=st;i<=nd;++i) ot(a[i]);putchar('\n');} namespace Miracle{
const int N=;
const int mod=1e9+;
int n,m;
int f[N][N][N],s[N][N][N];
int a[N];
int ad(int x,int y){
return x+y>=mod?x+y-mod:x+y;
}
void clear(){
memset(f,,sizeof f);memset(s,,sizeof s);
}
int main(){
int t;rd(t);
while(t--){
clear();
rd(n);rd(m);
for(reg i=;i<=n;++i) rd(a[i]);
f[][][]=;
for(reg j=;j<=n;++j) s[][j][]=;
for(reg i=;i<=n;++i){
int l=i,r=i;
while(l>&&a[l-]<a[i]) --l;
while(r<n&&a[r+]<a[i]) ++r;
// cout<<" i "<<i<<" : "<<l<<" and "<<r<<endl;
for(reg k=;k<=m;++k){
f[i][i][k]=ad(f[i][i][k],f[i-][i-][k]);
for(reg j=;j<=n;++j){
if(l<=j&&j<=r){
if(j==i){
if(j->=&&l->=) f[i][j][k]=ad(f[i][j][k],ad(s[i-][j-][k-],mod-s[i-][l-][k-]));
else if(j->=) f[i][j][k]=ad(f[i][j][k],s[i-][j-][k-]);
}else{
f[i][j][k]=ad(f[i][j][k],ad(s[i-][j-][k-],l->=?mod-s[i-][l-][k-]:));
}
}
f[i][j][k]=ad(f[i][j][k],f[i-][j][k]);
}
}
for(reg k=;k<=m;++k){
for(reg j=;j<=n;++j){
s[i][j][k]=f[i][j][k];
if(j) s[i][j][k]=ad(s[i][j][k],s[i][j-][k]);
}
}
}
// for(reg i=0;i<=n;++i){
// for(reg j=0;j<=n;++j){
// for(reg k=0;k<=m;++k){
// // cout<<" i j k "<<i<<" "<<j<<" "<<k<<" : "<<f[i][j][k]<<" s "<<s[i][j][k]<<endl;
// }
// }
// }
ll ans=;
for(reg k=;k<=m;++k) ans=ad(ans,f[n][n][k]);
printf("%lld\n",ans);
}
return ;
} }
signed main(){
Miracle::main();
return ;
} /*
Author: *Miracle*
*/
51nod1370 排列与操作的更多相关文章
- python字符串及字符串操作
字符串介绍 1.字符串在内存中的存储: 2.字符串相加: 3.字符串的格式化: In [1]: a = 100 In [2]: a Out[2]: 100 #100<255,在堆内存下占用了一个 ...
- Windows Store App 过渡动画
Windows Store App 过渡动画 在开发Windows应用商店应用程序时,如果希望界面元素进入或者离开屏幕时显得自然和流畅,可以为其添加过渡动画.过渡动画能够及时地提示用户屏幕所发 ...
- Learning WCF Chapter1 Exposing Multiple Service Endpoints
So far in this chapter,I have shown you different ways to create services,how to expose a service en ...
- tp剩余未验证内容-7
bash脚本中 的 set -e表示 exit immediately if a simple command returns a non-zero value.主要是为了防止错误被忽略.会被立即退出 ...
- SQL知识点、SQL语句学习
一. 数据库简介和创建1. 系统数据库在安装好SQL SERVER后,系统会自动安装5个用于维护系统正常运行的系统数据库: (1)master:记录了SQL SERVER实例的所有系统级消息,包括实例 ...
- Report CodeForces - 631C (栈)
题目链接 题目大意:给定序列, 给定若干操作, 每次操作将$[1,r]$元素升序或降序排列, 求操作完序列 首先可以发现对最后结果有影响的序列$r$一定非增, 并且是升序降序交替的 可以用单调栈维护这 ...
- 十分钟掌握pandas(pandas官方文档翻译)
十分钟掌握pandas 文档版本:0.20.3 这是一个对pandas简短的介绍,适合新用户.你可以在Cookbook中查看更详细的内容. 通常,我们要像下面一样导入一些包. In [1]: impo ...
- iOS开发——使用基于Autolayout的ScrollView
问题描述: 在使用Autolayout布局方式对ScrollView进行布局时,如果你想做一个可以垂直方向滚动的九宫格类似这样: 拿一行来说,一定不要想当然的尝试去给一行图标进行均匀排列的操作(指 ...
- Mongodb基本操作入门,增删改查和索引
主要进程 mongod.exe为启动数据库实例的进程. mongo是一个与mongod进程进行交互的JavaScript shell进程,它提供了一些交互的接口函数用户对数据库的管理. 基本命令 sh ...
随机推荐
- Markdown Linux
如何在Linux下使用Markdown进行文档工作 学习于: http://www.ituring.com.cn/article/10044 Markdown 官网: http://daringfir ...
- fusion-io工具--更换fusion-ioSSD无法识别及升级指引
centos6.5系统,(含fusion-io共7块盘)库存的fusion-io卡需要升级固件才能识别 现在只认到6个盘 fdisk -l 2>/dev/null | grep 'Disk /d ...
- 学习iOS设计--iOS8的颜色、文字和布局学习
在去年,Apple针对新时代用户彻底更新了其设计语言.现在的设计语言相对之前大为简化,能够让设计师将精力集中到动画和功能上,而不是繁复的视觉细节上. 很多人都曾问过我:设计应当如何入门?成为一名优秀设 ...
- Leetcode821.Shortest Distance to a Character字符的最短距离
给定一个字符串 S 和一个字符 C.返回一个代表字符串 S 中每个字符到字符串 S 中的字符 C 的最短距离的数组. 示例 1: 输入: S = "loveleetcode", C ...
- Leetcode804.Unique Morse Code Words唯一摩尔斯密码词
国际摩尔斯密码定义一种标准编码方式,将每个字母对应于一个由一系列点和短线组成的字符串, 比如: "a" 对应 ".-", "b" 对应 &q ...
- 洛谷P1879 玉米田
题目描述 农场主John新买了一块长方形的新牧场,这块牧场被划分成M行N列(1 ≤ M ≤ 12; 1 ≤ N ≤ 12),每一格都是一块正方形的土地.John打算在牧场上的某几格里种上美味的草,供他 ...
- 【C++】反向迭代器(rbegin,rend)(转载)
转自:http://blog.csdn.net/kjing/article/details/6936325 rbegin和rend,很有用! C++ primer (中文版第四版)第273页 9.3. ...
- 【JZOJ4833】【NOIP2016提高A组集训第3场10.31】Mahjong
题目描述 解法 搜索. 代码 #include<stdio.h> #include<iostream> #include<string.h> #include< ...
- navicat 导入SQL文件出错
1.新建数据库 在数据库名或者表名上右键 运行SQL语句 2.去掉对勾 F5刷新则可以发现导入的表.
- hihocoder 1586 ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛-题目9 : Minimum【线段树】
https://hihocoder.com/problemset/problem/1586 线段树操作,原来题并不难..... 当时忽略了一个重要问题,就是ax*ay要最小时,x.y可以相等,那就简单 ...