題意:
在范圍內滿足所給的運算符的數有多少個。
“/” 代表前面的比後面的小 “-”代表前面和後面一樣 “\” 代表前面的比後面的大
測試過會出現重復的符號 比如 "///\"
思路:
細心啊細心啊。。!!
數位dp,按位dp
注意幾個點就好了:
1、n個運算符至少要有n+1個數。
2、注意開始的狀態,第一個數以及第一個運算符。
3、運算符後移注意移動到結束標識就直接返回0。
4、運算符能往後移就往後移。
5、注意大數減一的計算。
6、注意減法的取模。
代碼:
#include"cstdlib" #include"cstdio" #include"cstring" #include"cmath" #include"queue" #include"algorithm" #include"iostream" using namespace std; //2014年9月26日12:49:21 __int64 dp[102][102][12]; int num[102],m=100000000; //因為8位數 所以對100000000取模 char v[102]; int ok(int n,int y,int z) { if(n>=101) //特判101 { if(n==101) n=0; else return 0; } if(v[n]=='\0') return 0; //注意如果字符串結束了 返回0 char x=v[n]; if(x=='/') return yz; } __int64 dfs(int site,int n,int cur,int zero,int f) //位數,運算符,前一個數,前導零,是否是邊界 { if(site==0) { if(zero) return 0; int tep=strlen(v)-1; //是否取到了最後一位 return tep==n; } if(!f&&!zero&&~dp[site][n][cur]) return dp[site][n][cur]; int len=f?num[site]:9; int ans=0; for(int i=0; i<=len; i++) { if(zero) { if(i==0) ans+=dfs(site-1,n,cur,zero&&i==0,f&&i==len); else { if(cur==10) ans+=dfs(site-1,101,i,zero&&i==0,f&&i==len); //首先第一位直接放進去 然後因為只有一個數還不能確定運算符 else { if(ok(n+1,cur,i)) ans+=dfs(site-1,n+1,i,zero&&i==0,f&&i==len); //這裡的原則是運算符能往後走就往後走 else if(ok(n,cur,i)) ans+=dfs(site-1,n==101?0:n,i,zero&&i==0,f&&i==len); //保持原樣,然後就是101代表第二個數 因為-1會越界 } } } else { if(cur==10) ans+=dfs(site-1,101,i,zero&&i==0,f&&i==len); else { if(ok(n+1,cur,i)) ans+=dfs(site-1,n+1,i,zero&&i==0,f&&i==len); else if(ok(n,cur,i)) ans+=dfs(site-1,n==101?0:n,i,zero&&i==0,f&&i==len); } } ans%=m; } if(!f&&!zero) dp[site][n][cur]=ans; return ans; } __int64 solve(char *x,int f) //f用來區分是否要減一 { int i=0,cnt=0; int len=strlen(x); while(x[i]=='0') i++; //去前導0 if(x[i]=='\0') return 0; //如果是0 for(int j=len-1; j>=i; j--) num[++cnt]=x[j]-'0'; //放入num if(f) //減一 { num[1]--; for(int j=1; j<=cnt; j++) { if(num[j]<0) { num[j]+=10; num[j+1]--; } } } if(num[cnt]==0) cnt--; //注意退位 return dfs(cnt,101,10,1,1); } int main() { while(scanf("%s",v)!=-1) { memset(dp,-1,sizeof(dp)); char x[123],y[123]; scanf("%s%s",x,y); //比較長 要用字符串讀入 printf("%08I64d\n",(solve(y,0)-solve(x,1)+m)%m); //減法一定注意取模。。 } return 0; } //2014年9月26日19:08:24