hdu_3886_Final Kichiku “Lanlanshu”(数位DP)

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=3886

题意:这题的题意有点晦涩难懂,大概意思就是给你一个区间,让你找一些满足递增递减条件的数,举个列:/-,要匹配这个关系,把一个数字分成一列数位,满足先递增,然后相等,然后递减的关系:ie:123321,1221,123441,这些都满足/-。

题解:设dp[i][j][k]表示考虑到第i位,上一个数为j,匹配关系到了k,然后DP下去就行了,注意处理左区间-1和前导零

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cmath>
 4 #define F(i,a,b) for(int i=a;i<=b;i++)
 5 typedef long long LL;
 6 char ops[111],a[111],b[111];
 7 int dig[111],st,len,oplen;
 8 LL N=(LL)1e10,dp[111][11][111];
 9 
10 int check(int pre,int now,int idx){
11     char c=ops[idx];
12     if(c=='/')return pre<now;
13     else if(c=='-')return pre==now;
14     return pre>now;
15 }
16 LL dfs(int pos,int idx=0,int pre=0,int z=0,bool inf=1){
17     if(!pos)return idx==oplen;
18     if(!inf&&~dp[pos][pre][idx])return dp[pos][pre][idx];
19     int end=inf?dig[pos]:9;LL ans=0;
20     F(i,0,end){
21         if(!z)ans+=dfs(pos-1,idx,i,z||i,inf&&i==end),ans%=N;
22         else if(idx<oplen&&check(pre,i,idx))
23             ans+=dfs(pos-1,idx+1,i,z||i,inf&&i==end),ans%=N;
24         else if(idx>0&&check(pre,i,idx-1))
25             ans+=dfs(pos-1,idx,i,z||i,inf&&i==end),ans%=N;
26     }
27     if(!inf)dp[pos][pre][idx]=ans;
28     return ans;
29 }
30 
31 void f_ck(){
32     memset(dp,-1,sizeof(dp));
33     oplen=strlen(ops);
34     for(st=0,len=0;a[st]=='0';)st++;
35     int end=strlen(a);
36     for(int i=end-1;i>=st;i--)dig[++len]=a[i]-'0';
37     dig[1]--;//处理左区间-1
38     for(int i=1;dig[i]<0;)dig[i]=9,dig[i+1]--;
39     LL tmp=(len==0)?0:dfs(len);
40     for(st=0,len=0;b[st]=='0';)st++;
41     end=strlen(b);
42     for(int i=end-1;i>=st;i--)dig[++len]=b[i]-'0';
43     LL an=dfs(len)-tmp+N;
44     printf("%08lld
",an%(LL)1e8);
45 }
46 
47 int main(){
48     while(~scanf("%s%s%s",ops,a,b))f_ck();
49     return 0;
50 }
View Code



原文地址:https://www.cnblogs.com/bin-gege/p/5696095.html