HDU-4507 数位DP 记录一个毒瘤错误orz
题意:求区间【L,R】满足以下性质:(1)数位中没有7,(2)数位和不被7整除,(3)数字本身不被7整除 的所有数字的平方和
先记录一个毒瘤错误。。。感觉自己好不会设状态啊。数位dp的状态自己都不知道是不是对的能不能转移QAQ。
错误代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define LL long long 5 using namespace std; 6 7 int a[20]; 8 LL dp[20][200][10]; 9 const int mod = 1e9+7; 10 11 LL dfs(int pos, int sum, LL n, bool lim){ 12 if (pos == -1) { 13 if (sum % 7 == 0) return 0; 14 if (n % 7 == 0) return 0; 15 return (n%mod)*(n%mod)%mod; 16 } 17 if (!lim && dp[pos][sum][n%7] != -1) return dp[pos][sum][n%7]; 18 LL ans = 0; 19 int r = lim ? a[pos] : 9; 20 for (int i = 0; i <= r; i++){ 21 if (i == 7) continue; 22 ans = (ans + dfs(pos-1, sum+i, n*10+i, lim && i == a[pos]) + mod) % mod; 23 } 24 if (!lim) dp[pos][sum][n%7] = ans; 25 return ans; 26 } 27 28 LL solve(LL x){ 29 int pos = 0; 30 while (x){ 31 a[pos++] = x%10; 32 x /= 10; 33 } 34 return dfs(pos-1, 0, 0, 1); 35 } 36 37 int main(){ 38 int t; 39 LL a, b; 40 scanf("%d", &t); 41 memset(dp, -1, sizeof dp); 42 while (t--){ 43 scanf("%lld%lld", &a, &b); 44 printf("%lld\n", (solve(b)-solve(a-1)+mod)%mod); 45 } 46 return 0; 47 }
AC代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define LL long long 5 using namespace std; 6 7 int a[20]; 8 LL p[30]; 9 const int mod = 1e9+7; 10 11 struct sta{ 12 LL cnt, ans, sum; 13 sta(LL cnt = 0, LL ans = 0, LL sum = 0): cnt(cnt), ans(ans), sum(sum){} 14 }dp[20][10][10]; 15 16 sta dfs(int pos, int sum, int n, bool lim){ 17 if (pos == -1) return sum != 0 && n != 0 ? sta(1, 0, 0) : sta(0, 0, 0); 18 if (!lim && dp[pos][sum][n].cnt != -1) return dp[pos][sum][n]; 19 sta ans(0, 0, 0); 20 int r = lim ? a[pos] : 9; 21 for (int i = 0; i <= r; i++){ 22 if (i == 7) continue; 23 sta nxt = dfs(pos-1, (sum+i)%7, (n*10+i)%7, lim && i == a[pos]); 24 ans.cnt = (ans.cnt + nxt.cnt) % mod; 25 ans.sum = (ans.sum + (nxt.sum + ((p[pos+1] * i) % mod) * nxt.cnt % mod) % mod) % mod; 26 ans.ans = (ans.ans + (nxt.ans + ((2*p[pos+1]*i) % mod) * nxt.sum) % mod) % mod; 27 ans.ans = (ans.ans + ((nxt.cnt * p[pos+1]) % mod * p[pos+1] % mod * i * i % mod)) % mod; 28 } 29 if (!lim) dp[pos][sum][n] = ans; 30 return ans; 31 } 32 33 LL solve(LL x){ 34 int pos = 0; 35 while (x){ 36 a[pos++] = x%10; 37 x /= 10; 38 } 39 return dfs(pos-1, 0, 0, 1).ans; 40 } 41 42 int main(){ 43 int t; 44 LL l, r; 45 scanf("%d", &t); 46 p[1] = 1; 47 for (int i = 2; i <= 20; i++) p[i] = (p[i-1]*10)%mod; 48 memset(dp, -1, sizeof dp); 49 while (t--){ 50 scanf("%lld%lld", &l, &r); 51 printf("%lld\n", (solve(r)-solve(l-1)+mod)%mod); 52 } 53 return 0; 54 }