您的位置:首页 > 其它

蒟蒻的数位DP专题总结

2015-11-14 14:04 295 查看
BZOJ 1026: [SCOI2009]windy数:

题目链接: http://www.lydsy.com/JudgeOnline/problem.php?id=1026
dp[11][11][2]:dep,pre,f

要求的性质就是相邻数字差至少是2。
递归函数的状态设计如下dep,pre,f,分别表示已经枚举到第dep位,他的前一位(更高的位)是pre,f表示大小关系是否已经确定.

///1085422276

#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std ;
typedef long long ll;
#define mem(a) memset(a,0,sizeof(a))
#define pb push_back
inline ll read()
{
ll x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')f=-1;ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';ch=getchar();
}return x*f;
}
//****************************************
const int  N=6000+50;
#define mod 10000007
#define inf 10000007
#define maxn 10000

ll dp[20][6000][20],vis[20][6000][20],d
;
ll dfs(int dep,int D,int mid,int f) {
if(dep<0) return D==3000;
if(f&&vis[dep][D][mid]) return dp[dep][D][mid];
if(f) {
vis[dep][D][mid]=1;
ll& re=dp[dep][D][mid];
for(int i=0;i<=9;i++) {
re+=dfs(dep-1,D-(dep-mid)*i,mid,f);
}
return re;
}
else {
ll re=0;
for(int i=0;i<=d[dep];i++) {
re+=dfs(dep-1,D-(dep-mid)*i,mid,i<d[dep]);
}
return re;
}

}
ll cal(ll x) {
if(x==0) return 1;
if(x<0) return 0;
int len=0;ll re=0;mem(dp),mem(vis);
while(x) d[len++]=x%10,x/=10;
for(int i=0;i<len;i++) {
re+=dfs(len-1,3000,i,0);
}
return re-len+1;
}
int main() {

int T=read();
while(T--) {
ll l,r;
scanf("%I64d%I64d",&l,&r);
cout<<cal(r)-cal(l-1)<<endl;
}
return 0;
}


HDU3709
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: