数位dp初探
我这种蒟蒻就一直不会写数位dp。。
于是开了个坑。。
1833: [ZJOI2010]count 数字计数
这道被KPM大爷说是入门题。。嗯似乎找找规律然后减掉0的情况后乱搞就可以了。。(但是还是写了很久TAT
#include<cstring>
#include<iostream>
#include<cstdio>
#include<queue>
#include<cmath>
#include<algorithm>
#define rep(i,l,r) for (int i=l;i<=r;i++)
#define down(i,l,r) for (int i=l;i>=r;i--)
#define clr(x,y) memset(x,y,sizeof(x))
#define low(x) (x&(-x))
#define maxn 505
#define inf int(1e9)
#define mm 1000000007
#define ll long long
using namespace std;
ll ans[][];
ll a,b,bin[];
ll read(){
ll x=,f=; char ch=getchar();
while (!isdigit(ch)) {if (ch=='-') f=-; ch=getchar();}
while (isdigit(ch)) {x=x*+ch-''; ch=getchar();}
return x*f;
}
int get(ll x){
if (x==) return ;
int ans=;
while(x){ans++; x/=;}
return ans;
}
void cal(ll x,int f){
int L,l=get(x),a; L=l;
rep(i,,) ans[i][f]=(l-)*bin[l-];
rep(i,,l-) ans[][f]-=bin[i];
while (l){
a=x/bin[l-];
if (l==L) rep(i,,a-) {
ans[i][f]+=bin[l-];
if (l->=) rep(j,,) ans[j][f]+=1LL*(l-)*bin[l-];
}
if (l!=L) rep(i,,a-) {
ans[i][f]+=bin[l-];
if (l->=) rep(j,,) ans[j][f]+=1LL*(l-)*bin[l-];
}
ans[a][f]+=x%bin[l-]+;
x=x%bin[l-];
l--;
}
}
int main(){
bin[]=; rep(i,,) bin[i]=bin[i-]*;
a=read(); b=read();
cal(a-,);
cal(b,);
rep(i,,) printf("%lld ",ans[i][]-ans[i][]);
printf("%lld\n",ans[][]-ans[][]);
return ;
}
1026: [SCOI2009]windy数
这道写个dp f[i][j]表示第i位最前一位数是j,特判一下0的情况。。
#include<cstring>
#include<iostream>
#include<cstdio>
#include<queue>
#include<cmath>
#include<algorithm>
#define rep(i,l,r) for (int i=l;i<=r;i++)
#define down(i,l,r) for (int i=l;i>=r;i--)
#define clr(x,y) memset(x,y,sizeof(x))
#define low(x) (x&(-x))
#define maxn 505
#define inf int(1e9)
#define mm 1000000007
#define ll long long
using namespace std;
int f[][],bin[];
int a,b;
int read(){
int x=,f=; char ch=getchar();
while (!isdigit(ch)) {if (ch=='-') f=-; ch=getchar();}
while (isdigit(ch)) {x=x*+ch-''; ch=getchar();}
return x*f;
}
int get(ll x){
if (x==) return ;
int ans=;
while(x){ans++; x/=;}
return ans;
}
int cal(int x){
int L,l=get(x),ans=,a,tmp=-; L=l;
if (l>) ans++;//0的情况
rep(i,,l-) {
rep(j,,) ans+=f[i][j];
}
while (l){
a=x/bin[l-];
if (l==L) rep(i,,a-) if (abs(i-tmp)>=){
rep(j,,) if (abs(i-j)>=) ans+=f[l-][j];
}
if (l!=L) rep(i,,a-) if (abs(i-tmp)>=){
rep(j,,) if (abs(i-j)>=) ans+=f[l-][j];
}
if (l==) rep(i,,a) if (abs(tmp-i)>=) ans++;
if (abs(tmp-a)<) break;
tmp=a;
x%=bin[l-];
l--;
}
return ans;
}
int main(){
bin[]=; rep(i,,) bin[i]=bin[i-]*;
a=read(); b=read();
int l=get(b);
rep(i,,) f[][i]=;
rep(i,,) rep(j,,) if (f[i][j]){
rep(k,,) if (abs(j-k)>=) f[i+][k]+=f[i][j];
}
printf("%d\n",cal(b)-cal(a-));
return ;
}
1072: [SCOI2007]排列perm
为什么我一直认为这道是状压。。 f[s][i]表示当前状态是s,模数为i。然后枚举每一个数是否被选过转移就可以了。
最后除掉相同数字个数的阶乘。
#include<cstring>
#include<iostream>
#include<cstdio>
#include<queue>
#include<cmath>
#include<algorithm>
#define rep(i,l,r) for (int i=l;i<=r;i++)
#define down(i,l,r) for (int i=l;i>=r;i--)
#define clr(x,y) memset(x,y,sizeof(x))
#define low(x) (x&(-x))
#define maxn 505
#define inf int(1e9)
#define mm 1000000007
#define ll long long
using namespace std;
int f[][];
int n,t,l,bin[],a[],num[],p[],ans;
char s[];
int read(){
int x=,f=; char ch=getchar();
while (!isdigit(ch)) {if (ch=='-') f=-; ch=getchar();}
while (isdigit(ch)) {x=x*+ch-''; ch=getchar();}
return x*f;
}
int main(){
t=read();
bin[]=; rep(i,,) bin[i]=bin[i-]*;
p[]=; rep(i,,) p[i]=p[i-]*i;
while (t--){
clr(f,); clr(num,);
scanf("%s",s); l=strlen(s);
int d=read();
rep(i,,l-) a[i]=s[i]-'',num[a[i]]++;
//printf("%d\n",bin[l]-1);
f[][]=;
rep(s,,bin[l]-) rep(j,,d-) if (f[s][j]){
rep(k,,l-) if ((s&bin[k])==) f[s+bin[k]][(j*+a[k])%d]+=f[s][j];
}
ans=f[bin[l]-][];
rep(i,,) if (num[i]) ans/=p[num[i]];
printf("%d\n",ans);
}
return ;
}
2425: [HAOI2010]计数
题目其实就是给你一些数字让你用这些数字构造一个个比给定数小的数。。
比如说我现在这一位最高为x,那就取0~x-1(可以有前导0)为这一位然后剩下的数自由组合。
对于这个自由组合,比如剩下有n位,这个数字还剩下有x个,那每一次就乘上C(n,x)然后n-=x。
#include<cstring>
#include<iostream>
#include<cstdio>
#include<queue>
#include<cmath>
#include<algorithm>
#define rep(i,l,r) for (int i=l;i<=r;i++)
#define down(i,l,r) for (int i=l;i>=r;i--)
#define clr(x,y) memset(x,y,sizeof(x))
#define low(x) (x&(-x))
#define maxn 505
#define inf int(1e9)
#define mm 1000000007
#define ll long long
using namespace std;
ll c[][],ans;
int cnt[],a[];
char s[];
int read(){
int x=,f=; char ch=getchar();
while (!isdigit(ch)) {if (ch=='-') f=-; ch=getchar();}
while (isdigit(ch)) {x=x*+ch-''; ch=getchar();}
return x*f;
}
ll cal(int n){
ll ans=;
int now=n;
rep(i,,) ans*=c[now][cnt[i]],now-=cnt[i];
return ans;
}
int main(){
c[][]=;
rep(i,,) {
c[i][]=;
rep(j,,) c[i][j]=c[i-][j-]+c[i-][j];
}
scanf("%s",s); int l=strlen(s);
rep(i,,l-) a[i+]=s[i]-'',cnt[a[i+]]++;
rep(i,,l) {
rep(j,,a[i]-) if (cnt[j]){
cnt[j]--;
ans+=cal(l-i);
cnt[j]++;
}
cnt[a[i]]--;
}
printf("%lld\n",ans);
return ;
}
BZOJ1799: [Ahoi2009]self 同类分布
http://www.cnblogs.com/ctlchild/p/5126952.html
(还有几道题目慢慢填TAT。。。
数位dp初探的更多相关文章
- 初探数位dp
数位dp有着很明显的特点,一般来说是给定区间[l,r]求满足某种条件区间中的数有多少个 朴素解法一般是O(n)的而n往往很大(10^8起步) 这时候我们就要想办法优化,于是就有了数位dp 数位有两个基 ...
- 数位类统计问题--数位DP
有一类与数位有关的区间统计问题.这类问题往往具有比较浓厚的数学味道,无法暴力求解,需要在数位上进行递推等操作.这类问题往往需要一些预处理,这就用到了数位DP. 本文地址:http://www.cnbl ...
- 数位dp入门 hdu2089 不要62
数位dp入门 hdu2089 不要62 题意: 给定一个区间[n,m] (0< n ≤ m<1000000),找出不含4和'62'的数的个数 (ps:开始以为直接暴力可以..貌似可以,但是 ...
- 动态规划——数位dp
通过先前在<动态规划——背包问题>中关于动态规划的初探,我们其实可以看到,动态规划其实不是像凸包.扩展欧几里得等是具体的算法,而是一种在解决问题中决策的思想.在不同的题目中,我们都需要根据 ...
- [bzoj1833][ZJOI2010]count 数字计数——数位dp
题目: (传送门)[http://www.lydsy.com/JudgeOnline/problem.php?id=1833] 题解: 第一次接触数位dp,真的是恶心. 首先翻阅了很多很多一维dp,因 ...
- 【BZOJ1662】[Usaco2006 Nov]Round Numbers 圆环数 数位DP
[BZOJ1662][Usaco2006 Nov]Round Numbers 圆环数 Description 正如你所知,奶牛们没有手指以至于不能玩"石头剪刀布"来任意地决定例如谁 ...
- bzoj1026数位dp
基础的数位dp 但是ce了一发,(abs难道不是cmath里的吗?改成bits/stdc++.h就过了) #include <bits/stdc++.h> using namespace ...
- uva12063数位dp
辣鸡军训毁我青春!!! 因为在军训,导致很长时间都只能看书yy题目,而不能溜到机房鏼题 于是在猫大的帮助下我发现这道习题是数位dp 然后想起之前讲dp的时候一直在补作业所以没怎么写,然后就试了试 果然 ...
- HDU2089 不要62[数位DP]
不要62 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
随机推荐
- Vue购物车实例
<div class="buyCarBox" id="buyCarBox" v-cloak> <div class="haveClo ...
- button的用法
C# 如何去掉button按钮的边框线? 设置FlatStyle为Flat,并且设置FlatAppearance下的BorderSize为0.
- web调用客户端程序
背景 最近做一个集成需求,我们是B/S架构的,对方是C/S架构的,对方直接扔过来一个EXE连OCX都没有,让我们调用,也就是说,我们需要通过js程序去调用他们的客户端程序并传入多个参数,当时内心是崩溃 ...
- Java中的集合概述
Java中的集合类有两个重要的分支,分别是接口Collection(包括List,Set等)和接口Map. 由于HashSet的内部实现原理使用了HashMap,所以我们先来了解Map集合类. 1.H ...
- ElasticSearch 学习记录之ES查询添加排序字段和使用missing或existing字段查询
ES添加排序 在默认的情况下,ES 是根据文档的得分score来进行文档额排序的.但是自己可以根据自己的针对一些字段进行排序.就像下面的查询脚本一样.下面的这个查询是根据productid这个值进行排 ...
- Neo4j学习笔记(1)——使用API编写一个Hello World程序
项目的创建及配置 因为Neo4j依赖的jar包比较多,所以推荐使用Maven来管理. 首先创建一个Maven Project,添加依赖: <dependency> <groupId& ...
- 获取数据库时间sql 以及行级锁总结-共享锁-排他锁-死锁
--TRUNC(date,[fmt]) /TRUNC(number[,decimals])SELECT SYSDATE FROM dual;SELECT TRUNC(SYSDATE) FROM dua ...
- 《Django By Example》Chap 4中出现的 “RelatedObjectDoesNotExist”错误
models.py
- 正则验证,match()与test()函数的区别?
test是RegExp的方法,参数是字符串,返回值是boolean类型.match是String的方法,参数是正则表达式,返回值是数组. 案例: //判断日期类型是否为YYYY-MM-DD格式的类型 ...
- 视觉SLAM的方案总结
MoNoSLAM:https://github.com/hanmekim/SceneLib2 以扩展卡尔曼滤波为后端,追踪前端非常稀疏的特征点,以相机的当前状态和所有路标点为状态量,更新其均值和协方差 ...