HDU6148 Valley Numer (2017百度之星程序设计大赛 - 复赛)
2017-08-23 19:42
459 查看
数位dp
题目传送门算法应该很好想吧。。。
三维f
[pre][now]表示第n位前一位数字为pre时,当前状态为now时的Valley Numer总数。(flag=0表示当前为递减,flag=1表示当前为递增)
dfs求f即可。
注意前导0。
代码:
#include<cstdio> #include<cstring> #include<algorithm> #define MAXN 100 #define MOD 1000000007 using namespace std; int f[MAXN+5][MAXN+5][2],a[MAXN+5]; int t; char s[MAXN+5]; int dfs(int n,int now,int pre,int flag){//当前长度为n,当前状态为now,前一位数字为pre,当前限制为flag if (!n)//如果是最后一位 return 1; if (!flag&&f [pre][now])//如果并没有限制并且已经被更新过 return f [pre][now];//直接返回值 int ma; if (flag)//如果有限制 ma=a ; else ma=9; int sum=0; if (now) for (int i=pre;i<=ma;i++) sum=(sum+dfs(n-1,now,i,flag&&i==ma))%MOD; else for (int i=0;i<=ma;i++) if (i>pre)//如果开始递增 sum=(sum+dfs(n-1,1,i,flag&&i==ma))%MOD; else if (!i&&pre==10)//如果有前导0 sum=(sum+dfs(n-1,0,10,flag&&i==ma))%MOD; else sum=(sum+dfs(n-1,0,i,flag&&i==ma))%MOD; if (!flag)//如果并没有限制 f [pre][now]=sum; return sum; } int main(){ scanf("%d",&t); while (t--){ memset(s,0,sizeof(s)); scanf("%s",s); int n=strlen(s); for (int i=0;i<n;i++) a[n-i]=s[i]-'0'; memset(f,0,sizeof(f)); printf("%d\n",(dfs(n,0,10,1)-1+MOD)%MOD); } return 0; }
相关文章推荐
- 2017百度之星程序设计大赛 - 复赛 Arithmetic of Bomb
- HDU6144 Arithmetic of Bomb (2017百度之星程序设计大赛 - 复赛)
- 【TEST】2017百度之星程序设计大赛 - 复赛
- Hdu6144 Arithmetic of Bomb(2017百度之星程序设计大赛 - 复赛)
- 【2017百度之星程序设计大赛 - 复赛】Valley Numer
- Hdu6146 Pokémon GO(2017百度之星程序设计大赛 - 复赛)
- HDU6147(2017百度之星程序设计大赛 - 复赛)[Pokémon GO II]--找规律
- 2017百度之星程序设计大赛 - 复赛 HDU-6149:Valley Numer II
- [2017百度之星程序设计大赛 - 复赛]E - hdu6148
- 2017百度之星程序设计大赛 - 复赛 题解(1,3)
- [2017百度之星程序设计大赛 - 复赛]A - hdu6144 B - hdu6145
- [2017百度之星程序设计大赛 - 复赛]F - hdu6149
- [2017百度之星程序设计大赛- 复赛] C - hdu6146
- HDU6147 Pokémon GO II (2017百度之星程序设计大赛 - 复赛)
- HDU6146 Pokémon GO (2017百度之星程序设计大赛 - 复赛)
- [2017百度之星程序设计大赛 - 复赛]D - hdu6147
- HDU6146(2017百度之星程序设计大赛 - 复赛)[Pokémon GO]--DP
- [反演] 2017 计蒜之道 复赛 A. 阿里云秘钥池
- 【数位DP+莫比乌斯函数】2017计蒜之道复赛A[阿里云秘钥池]题解
- 2017 计蒜之道 复赛 腾讯消消乐【状压dp】