【BZOJ】1026 [SCOI2009]windy数 数位dp
2017-05-31 19:22
573 查看
题目传送门
感觉自己真的是越来越菜了,连数位dp都写不来了……
定义f[i][j]表示当前取到第i位(从高位到低位),当前位置为j的方案数。
然后就是对于是否存在前导0的分类讨论,并同时统计答案。
最后利用差分的思想,把[l,r]的windy数的数量转化成[1,r]的windy数的数量减去[1,l-1]的windy数的数量即可。
附上AC代码:
#include <cstdio>
#include <cctype>
using namespace std;
const int n=9;
int a,b,f[11][11],ans1,ans2,dig[11];
inline char nc(){
static char ch[100010],*p1=ch,*p2=ch;
return p1==p2&&(p2=(p1=ch)+fread(ch,1,100010,stdin),p1==p2)?EOF:*p1++;
}
inline void read(int &a){
static char c=nc();int f=1;
for (;!isdigit(c);c=nc()) if (c=='-') f=-1;
for (a=0;isdigit(c);a=a*10+c-'0',c=nc());
a*=f;return;
}
inline int abs(int a){
return a>0?a:-a;
}
inline int count(int x){
if (!x) return 0;
int len=0,sum=0;
while (x) dig[++len]=x%10,x/=10;
for (int i=len; i; --i){
if (len-i>=2&&abs(dig[i+1]-dig[i+2])<2) break;
for (int j=0+(i==len); j<dig[i]+(i==1); ++j)
if (i==len||abs(j-dig[i+1])>=2) sum+=f[i][j];
}
for (int i=len-1; i; --i)
for (int j=1; j<=n; ++j)
sum+=f[i][j];
return sum;
}
int main(void){
read(a),read(b);
for (int i=0; i<=n; ++i) f[1][i]=1;
for (int i=2; i<=10; ++i)
for (int j=0; j<=n; ++j)
for (int k=0; k<=n; ++k)
if (abs(j-k)>=2) f[i][j]+=f[i-1][k];
printf("%d",count(b)-count(a-1));
return 0;
}
感觉自己真的是越来越菜了,连数位dp都写不来了……
定义f[i][j]表示当前取到第i位(从高位到低位),当前位置为j的方案数。
然后就是对于是否存在前导0的分类讨论,并同时统计答案。
最后利用差分的思想,把[l,r]的windy数的数量转化成[1,r]的windy数的数量减去[1,l-1]的windy数的数量即可。
附上AC代码:
#include <cstdio>
#include <cctype>
using namespace std;
const int n=9;
int a,b,f[11][11],ans1,ans2,dig[11];
inline char nc(){
static char ch[100010],*p1=ch,*p2=ch;
return p1==p2&&(p2=(p1=ch)+fread(ch,1,100010,stdin),p1==p2)?EOF:*p1++;
}
inline void read(int &a){
static char c=nc();int f=1;
for (;!isdigit(c);c=nc()) if (c=='-') f=-1;
for (a=0;isdigit(c);a=a*10+c-'0',c=nc());
a*=f;return;
}
inline int abs(int a){
return a>0?a:-a;
}
inline int count(int x){
if (!x) return 0;
int len=0,sum=0;
while (x) dig[++len]=x%10,x/=10;
for (int i=len; i; --i){
if (len-i>=2&&abs(dig[i+1]-dig[i+2])<2) break;
for (int j=0+(i==len); j<dig[i]+(i==1); ++j)
if (i==len||abs(j-dig[i+1])>=2) sum+=f[i][j];
}
for (int i=len-1; i; --i)
for (int j=1; j<=n; ++j)
sum+=f[i][j];
return sum;
}
int main(void){
read(a),read(b);
for (int i=0; i<=n; ++i) f[1][i]=1;
for (int i=2; i<=10; ++i)
for (int j=0; j<=n; ++j)
for (int k=0; k<=n; ++k)
if (abs(j-k)>=2) f[i][j]+=f[i-1][k];
printf("%d",count(b)-count(a-1));
return 0;
}
相关文章推荐
- bzoj 1026: [SCOI2009]windy数【数位dp】
- [SCOI 2009]BZOJ 1026 windy数 - 数位dp
- [bzoj1026][SCOI2009]windy数_数位dp
- bzoj 1026: [SCOI2009]windy数(数位dp)
- BZOJ 1026 [SCOI2009]windy数【数位DP】
- _bzoj1026 [SCOI2009]windy数【数位dp】
- BZOJ_1026_[SCOI2009]_windy数_(数位dp)
- bzoj1026: [SCOI2009]windy数 数位dp
- bzoj:1026: [SCOI2009]windy数(数位dp)
- BZOJ_1026_[SCOI2009]windy数_数位DP
- BZOJ 1026 [SCOI2009]windy数 数位dp
- [BZOJ 1026][SCOI 2009]windy数(数位DP)
- BZOJ 1026: [SCOI2009]windy数 【数位dp】
- BZOJ 1026: [SCOI2009]windy数 数位DP
- BZOJ 1026 [SCOI2009]windy数 数位DP?
- 【BZOJ1026】【SCOI2009】windy数(数位dp)
- HDU2089 不要62 BZOJ1026: [SCOI2009]windy数 [数位DP]
- 【数位DP】bzoj1026: [SCOI2009]windy数
- BZOJ 1026([SCOI2009]windy数-数位DPlevel up)
- [BZOJ1026]SCOI2009 windy数|数位DP