首页 > 其他 > 详细

HDU 5632 Rikka with Array [想法题]

时间:2016-02-29 00:38:29      阅读:207      评论:0      收藏:0      [点我收藏+]

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

------------------------------------------------------------------------------------------

这场比赛的官方题解说这题比较明显, 然而我比赛完后对着题解看了好久也没有想明白

于是先做了几道数位$DP$找找感觉 可惜感觉并没有找到

这题和传统数位$DP$不一样 这题是求范围内满足要求的数对的个数

既然是数对 我们记录时便不再记录数的状态 而是记录两数之间的关系的状态

不过官方题解只记录 考虑到了哪位 两数$1$的个数差的绝对值

大数$1$的个数是否不小于小数$1$的个数 这三个部分

可惜自己做的时候总感觉只记录这些状态还不够

然后$Cwind$前辈提供了一个思路 额外记录两个部分

大小两数当前位之前是否相等 大数当前位之前是否与限制条件相等

------------------------------------------------------------------------------------------

用以上的思路就可以比较轻松的用记忆化搜索做了

不过由于状态多两维 而且目前写法每次询问都需要重新计算 因而时间比较挫 要$1.4s$

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cmath>
 4 #include <algorithm>
 5 using namespace std;
 6 const int N = 1000, mod = 998244353;
 7 int f[N][N][2][2][2], cnt[N][N][2][2][2];
 8 bool bin[N];
 9 int num[310];
10 char s[310];
11 int t, len, n;
12 void init()
13 {
14     n = 0;
15     while(len)
16     {
17         for(int i = len; i; --i)
18         {
19             num[i - 1] += (num[i] & 1) * 10;
20             num[i] >>= 1;
21         }
22         bin[++n] = (num[0] != 0);
23         num[0] = 0;
24         if(!num[len])
25             --len;
26     }
27 }
28 int dfs(int x, int dif, bool over, bool same, bool top)
29 {
30     if(cnt[x][dif][over][same][top] == t + 1)
31         return f[x][dif][over][same][top];
32     cnt[x][dif][over][same][top] = t + 1;
33     if(!x)
34         return f[x][dif][over][same][top] = !over && !same;
35     int re = 0;
36     if(!top || bin[x])
37     {
38         re += dfs(x - 1, dif, over, same, top);
39         re += dfs(x - 1, dif + (over ? 1 : -1), over || dif == 1, 0, top);
40         re = (re >= mod ? re - mod : re);
41     }
42     if(!same)
43     {
44         re += dfs(x - 1, abs(dif + (over ? -1 : 1)), over && dif, 0, top && !bin[x]);
45         re = (re >= mod ? re - mod : re);
46     }
47     re += dfs(x - 1, dif, over, same, top && !bin[x]);
48     re = (re >= mod ? re - mod : re);
49     return f[x][dif][over][same][top] = re;
50 }
51 int main()
52 {
53     scanf("%d", &t);
54     while(t--)
55     {
56         scanf("%s", s + 1);
57         len = strlen(s + 1);
58         for(int i = 1; i <= len; ++i)
59             num[i] = s[len - i + 1] - 0;
60         init();
61         printf("%d\n", dfs(n, 0, 1, 1, 1));
62     }
63     return 0;
64 }

想到/理解了 更好的方法再来改改吧

HDU 5632 Rikka with Array [想法题]

原文:http://www.cnblogs.com/sagitta/p/5225991.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!