1026: [SCOI2009]windy数
题目:
http://www.lydsy.com/JudgeOnline/problem.php?id=1026
数位dp。f[i][j]表示i位数最高位为j的windy数个数。
可以将问题转化为求0~n的windy数个数。
设n为m位数,则可以先求出1~m-1位数的windy数个数,然后计算m位数。
从高位往低位计算(这样上一位是确定的),需要注意的是检查上一位和上上位,看是否满足windy数,不满足可以直接退出。
#include
<
iostream
>
#include
<
cstring
>
#include
<
cstdlib
>
#include
<
cstdio
>
#include
<
cmath
>
using
namespace
std;
const
int
MaxN
=
15
;
int
n;
long
long
f[MaxN][
10
],a,b;
long
long
work(
long
long
a)
{
if
(a
<
0
)
{
return
0
;
}
if
(a
==
0
)
{
return
1
;
}
int
n
=
(
int
)log10(a)
+
1
;
long
long
tot
=
1
;
for
(
int
i
=
1
;i
<
n;i
++
)
{
for
(
int
j
=
1
;j
<=
9
;j
++
)
{
tot
+=
f[i][j];
}
}
int
last
=-
2
;
long
long
p
=
1
;
bool
flag
=
0
;
if
(n
==
1
)
{
flag
=
1
;
}
for
(;n
!=
0
;a
%=
p,n
--
)
{
long
long
t
=
a;
p
=
1
;
for
(
int
i
=
0
;i
<
n
-
1
;i
++
)
{
t
/=
10
;
p
*=
10
;
}
for
(
int
i
=
0
;i
<
t;i
++
)
{
if
(i
==
0
&&
flag
==
0
)
{
continue
;
}
if
(abs(i
-
last)
>
1
)
{
tot
+=
f[n][i];
}
}
if
(n
==
1
)
{
if
(abs(t
-
last)
>
1
)
{
tot
++
;
}
}
if
(abs(last
-
t)
<=
1
)
{
break
;
}
last
=
t;
flag
=
1
;
}
return
tot;
}
void
treat()
{
for
(
int
i
=
0
;i
<=
9
;i
++
)
{
f[
1
][i]
=
1
;
}
for
(
int
i
=
2
;i
<=
n;i
++
)
{
for
(
int
j
=
0
;j
<=
9
;j
++
)
{
f[i][j]
=
0
;
for
(
int
k
=
0
;k
<=
9
;k
++
)
{
if
(abs(j
-
k)
>
1
)
{
f[i][j]
+=
f[i
-
1
][k];
}
}
}
}
}
int
main()
{
cin
>>
a
>>
b;
a
--
;
n
=
log10(b)
+
1
;
treat();
cout
<<
work(b)
-
work(a)
<<
endl;
return
0
;
}
posted on 2013-02-13 14:45
Kiro
阅读(96)
评论(0)
编辑
收藏
引用
所属分类:
衡八oj
只有注册用户
登录
后才能发表评论。
相关文章:
1055: [HAOI2008]玩具取名
1054: [HAOI2008]移动玩具
1051: [HAOI2006]受欢迎的牛
1050: [HAOI2006]旅行comf
1046: [HAOI2007]上升序列
1042: [HAOI2008]硬币购物
1037: [ZJOI2008]生日聚会Party
1034: [ZJOI2008]泡泡堂BNB
1029: [JSOI2007]建筑抢修
1027: [JSOI2007]合金
网站导航:
博客园
博客园最新博文
博问
管理
4myOI
再给我一次机会将故事改写。
导航
C++博客
首页
新随笔
联系
聚合
管理
统计
随笔 - 0
文章 - 27
评论 - 0
引用 - 0
常用链接
我的随笔
我的评论
我参与的随笔
留言簿
给我留言
查看公开留言
查看私人留言
文章分类
■
hdu(1)
(rss)
■
poj(2)
(rss)
■
衡八oj(24)
(rss)
■
其他
(rss)
文章档案
■
2013年2月 (17)
■
2013年1月 (3)
■
2012年10月 (3)
■
2012年9月 (1)
■
2012年3月 (1)
■
2012年2月 (2)
搜索
最新评论