哈尔滨理工大学软件与微电子学院第八届程序设计竞赛同步赛(高年级) A 小乐乐的组合数+ 【规律】

任意门:https://ac.nowcoder.com/acm/contest/301/A

题意概括:

链接:https://ac.nowcoder.com/acm/contest/301/A
来源:牛客网

小乐乐得知一周有7天之后就对7产生了兴趣。
小乐乐得到了两堆数字数字时连续的。
第一堆包含[1,n]n个数字,第二堆包含[1,m]m个数字。
小乐乐想要从两堆中各挑选出一个整数x,y,使得x,y的和为7的倍数。

请问小乐乐有多少种组合的方式。

解题思路:

一开始想 O(1) 解决查询。

在一个特殊情况 卡 了:

输入N M 调整使得 N < M

那么我们其实就是遍历 N 来得出最后的结果。

很明显 只要满足了 给第 i 个数 (7 - i % 7)那么剩下有多少个七就说明 i 有多少种可能

然后把 i 累加起来最后得到的答案 就是 最后的方案数了。

然而天真的我想要 简化这条式子 最后傻傻的简化成了 ans = N*M - N + (N/7)+N%7;

这条式子 bug 在了处理 m 等于 8 这种边界值的情况,并没有把递推的性质完全继承下来。

而这道题一个for循环遍历 N 求和 是在复杂度范围之内的,对复杂度的估算有误。

最后找出了递推式,一次遍历,搞定。

果然,比赛才是王道,赛时打了表,找了个规律,wa,心态爆炸 太久没打dp 以至于一开始 E 题很明显的最长公共子序列都卡死了,

赛后冷静下来,硬生生地把递推式弄出来。

那些挖了的坑没有填,现在成功把自己坑了,dp,搜索怎么能丢呢。

AC code:

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <cmath>
 6 #include <map>
 7 #define INF 0x3f3f3f3f
 8 #define LL long long
 9 using namespace std;
10 
11 LL N, M;
12 
13 LL inv(LL x, LL p)
14 {
15     LL res = 1LL;
16     while(p){
17         if(p&1LL) res*=x%7LL;
18         x*=x;
19         p>>=1;
20     }
21     return res;
22 }
23 int main()
24 {
25     while(~scanf("%lld %lld", &N, &M)){
26         LL ans = 0LL;
27         if(N > M) swap(N, M);
28         if(M < 7LL){
29             ans = 0;
30             for(LL i = 1LL; i <= N; i++)
31                 if(M >= (7LL-i)) ans++;
32         }
33         else{
34 //            ans = (N*M)-7*N;
35 //            ans = ans + 21*(N/7);
36 //            if(N > 7)
37 //            for(int i = 1; i <= N%7; i++)
38 //                ans+=i;
39 //            ans = ans/7 + N;
40             ans = N;
41             for(LL i = 1LL; i <= N; i++){
42                 ans += (M-(7LL-i%7))/7LL;
43             }
44         }
45         printf("%lld\n", ans);
46     }
47     return 0;
48 }

猜你喜欢

转载自www.cnblogs.com/ymzjj/p/10052020.html