哈爾濱理工大學軟體與微電子學院第八屆程式設計競賽同步賽(高年級) A 小樂樂的組合數+ 【規律】
阿新 • • 發佈:2018-12-02
任意門:https://ac.nowcoder.com/acm/contest/301/A
題意概括:
連結:https://ac.nowcoder.com/acm/contest/301/A
來源:牛客網
小樂樂想要從兩堆中各挑選出一個整數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 usingnamespace 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 }