SOJ 4265: story of 206
2013-04-16 12:49
239 查看
其实我出这道题的心态还是挺健康的,
就是学习了一种很简洁的数位DP方法,
想推荐给大家。
结果这道题比赛的时候只有三个人开,
且最后只有一个过,
哭了。。。
赛后给开了这道题的三个人都发了标程。
然后就没有然后了。。
sigh。。。。
其实DP还是多有趣的。。。
小盆友们要多学习一下啊~~~
题目链接:http://cstest.scu.edu.cn/soj/problem.action?id=4265
题意:给定一个闭区间,问该区间中满足含有“206”这个子串并且任意相邻两位数字均不相同的数有多少个。
算法:
枚举数的位数记忆化搜索。
数组需记录四维变量。
fst表示当前位置是否是首位。
len表示当前处理的是串的第len位。
s表示当前串含有的“206”前缀(例如可以用0表示无前缀,1表示“2”,2表示“20”,3表示“206”等等)。
pre表示当前位的前一位是哪个数字。
然后根据记录的信息枚举各位置的数字状态转移即可。
代码如下:
#include<cstdio>
#include<cstring>
using namespace std;
long long d[2][20][4][10];
long long dig[20];
int ns(int s,int i) {
if(s==3||(s==2&&i==6)) {
return 3;
}
if(s==1&&i==0) {
return 2;
}
if(i==2) {
return 1;
}
return 0;
}
long long dp(bool less,bool fst,int len,int s,int pre) {
if(len==-1) {
return less&&s==3;
}
if(less&&d[fst][len][s][pre]!=-1) {
return d[fst][len][s][pre];
}
long long ret=0LL;
for(int i=0; i<10; i++) {
if(!less&&i>dig[len]) {
continue;
}
if(i==pre) {
continue;
}
if(fst&&!i) {
continue;
}
ret+=dp(less||i<dig[len],false,len-1,ns(s,i),i);
}
if(less) {
d[fst][len][s][pre]=ret;
}
return ret;
}
long long solve(long long x) {
int len=0;
while(x) {
dig[len++]=x%10;
x/=10;
}
long long ret=0LL;
for(int i=0; i<len; i++) {
ret+=dp(i<len-1,true,i,0,-1);
}
return ret;
}
int main() {
int cas;
scanf("%d",&cas);
memset(d,-1,sizeof(d));
while(cas--) {
long long a,b;
scanf("%lld%lld",&a,&b);
printf("%lld\n",solve(b+1)-solve(a));
}
return 0;
}
就是学习了一种很简洁的数位DP方法,
想推荐给大家。
结果这道题比赛的时候只有三个人开,
且最后只有一个过,
哭了。。。
赛后给开了这道题的三个人都发了标程。
然后就没有然后了。。
sigh。。。。
其实DP还是多有趣的。。。
小盆友们要多学习一下啊~~~
题目链接:http://cstest.scu.edu.cn/soj/problem.action?id=4265
题意:给定一个闭区间,问该区间中满足含有“206”这个子串并且任意相邻两位数字均不相同的数有多少个。
算法:
枚举数的位数记忆化搜索。
数组需记录四维变量。
fst表示当前位置是否是首位。
len表示当前处理的是串的第len位。
s表示当前串含有的“206”前缀(例如可以用0表示无前缀,1表示“2”,2表示“20”,3表示“206”等等)。
pre表示当前位的前一位是哪个数字。
然后根据记录的信息枚举各位置的数字状态转移即可。
代码如下:
#include<cstdio>
#include<cstring>
using namespace std;
long long d[2][20][4][10];
long long dig[20];
int ns(int s,int i) {
if(s==3||(s==2&&i==6)) {
return 3;
}
if(s==1&&i==0) {
return 2;
}
if(i==2) {
return 1;
}
return 0;
}
long long dp(bool less,bool fst,int len,int s,int pre) {
if(len==-1) {
return less&&s==3;
}
if(less&&d[fst][len][s][pre]!=-1) {
return d[fst][len][s][pre];
}
long long ret=0LL;
for(int i=0; i<10; i++) {
if(!less&&i>dig[len]) {
continue;
}
if(i==pre) {
continue;
}
if(fst&&!i) {
continue;
}
ret+=dp(less||i<dig[len],false,len-1,ns(s,i),i);
}
if(less) {
d[fst][len][s][pre]=ret;
}
return ret;
}
long long solve(long long x) {
int len=0;
while(x) {
dig[len++]=x%10;
x/=10;
}
long long ret=0LL;
for(int i=0; i<len; i++) {
ret+=dp(i<len-1,true,i,0,-1);
}
return ret;
}
int main() {
int cas;
scanf("%d",&cas);
memset(d,-1,sizeof(d));
while(cas--) {
long long a,b;
scanf("%lld%lld",&a,&b);
printf("%lld\n",solve(b+1)-solve(a));
}
return 0;
}
相关文章推荐
- 206_12_15炸弹人开发日志
- Oracle Bug 4401119 for AIX Database crashes with ORA-221, ORA-206, ORA-202, ORA-27072
- SOJ 3598 Binary
- 【归并树】soj 3010 kth number
- SOJ 3137: Simple Computing _容斥原理
- SOJ 1824 并查集
- SOJ 2209 递推 大数
- SOJ 4243: Saving Girl
- soj 1135. 飞越原野
- soj 1754. 逃离洞穴
- NYOJ-206:矩形的个数
- Next Mayor--SOJ 2013week2.1000
- SGU 206 Roads
- Sicily 1444 Prime Path (SOJ 1444) 【BFS 广度优先搜索】
- SOJ 4299: component
- SOJ 1052. Candy Sharing Game
- soj 1509 rails 栈的应用
- 关于eclipse运行TestNG出现: CreateProcess error=206, ÎļþÃû»ò)չÃû的解决办法
- soj 1698 Hungry Cow_三角函数
- soj 1324. Score