SPOJ BALNUM Balanced Numbers(数位DP+状态压缩)题解
2024-10-17 01:33:57
思路:
把0~9的状态用3进制表示,数据量3^10
代码:
#include<cstdio>
#include<map>
#include<set>
#include<queue>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define ll long long
const int N = 500+5;
const int INF = 0x3f3f3f3f;
using namespace std;
int dp[22][60000]; //0 没出现,1 奇数,2 偶数
int dig[22];
int check(int sta){
for(int i = 0;i <= 9;i++){
int tmp = sta % 3;
sta /= 3;
if(i % 2 == 1 && tmp == 1) return 0;
else if(i % 2 == 0 && tmp == 2) return 0;
}
return 1;
}
int news(int sta,int x){
int num[10];
for(int i = 0;i <= 9;i++){
num[i] = sta % 3;
sta /= 3;
}
int tmp = 0;
if(num[x] == 0) num[x] = 1;
else num[x] = 3 - num[x];
for(int i = 9;i >= 0;i--){
tmp = tmp*3 + num[i];
}
return tmp;
}
ll dfs(int pos,int sta,bool lead,bool limit){
if(pos == -1) return check(sta);
if(!limit && dp[pos][sta] != -1) return dp[pos][sta];
int top = limit? dig[pos] : 9;
ll ret = 0;
for(int i = 0;i <= top;i++){
int STA = news(sta,i);
if(lead && i == 0) STA = 0;
ret += dfs(pos - 1,STA,lead && i == 0,limit && i == top);
}
if(!limit) dp[pos][sta] = ret;
return ret;
}
ll solve(ll x){
int pos = 0;
if(x == 0) return 1;
while(x){
dig[pos++] = x % 10;
x /= 10;
}
return dfs(pos - 1,0,true,true);
}
int main(){
int T;
ll a,b;
scanf("%d",&T);
memset(dp,-1,sizeof(dp));
while(T--){
scanf("%lld%lld",&a,&b);
printf("%lld\n",solve(b) - solve(a - 1));
}
return 0;
}
最新文章
- A trip through the Graphics Pipeline 2011_08_Pixel processing – “fork phase”
- Yii源码阅读笔记(二)
- Android IOS WebRTC 音视频开发总结(四九)-- ffmpeg介绍
- centos安装redis3为系统服务
- IIS Web负载均衡的几种方式
- Linux网络应用编程之VLAN(Packet Tracer仿真)
- 关于Java(JDBC连接数据库)
- 转:基于ASP.NET的Comet长连接技术解析
- hdu3410-Passing the Message(RMQ,感觉我写的有点多此一举。。。其实可以用单调栈)
- D1-Linux-CentOS学习打卡
- SQL过滤字符后手工注入漏洞测试(第1题)
- Dijkstra求最短路径&;例题
- linux 校准时间方法
- 安装nginx流程
- HTTP Basic Authentication认证(Web API)
- 编写安全的API接口
- Redis (1) —— 安装
- Tomcat修改端口和编码配置
- operator new 和 operator delete 实现一个简单内存泄漏跟踪器
- window环境下安装Python2和Python3