有一道經典問題是這樣子的:
「給予一個n,請計算n∑k=1⌊nk⌋」
1 2 3 4 5 6 7 8 9 10 11 | #include <bits/stdc++.h> int main() { int n,ans=0; scanf("%d",&n); for(int i=1;i<=n;i++) ans+=n/i; printf("%d\n",ans); return 0; } |
可惜這樣子的時間複雜度是O(n),實在太慢了。
可以發現這n項當中有許多項是一樣的,藉此加速便可達到O(√n)。
code長這樣子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #include <bits/stdc++.h> int main() { int n,ans=0; scanf("%d",&n); for(int i=1;i<=n;) { int t=n/(n/i); ans+=(n/i)*(t-i+1); i=t+1; } printf("%d\n",ans); return 0; } |
事實是:第9行那個動作可以精確的取到最大整數的t滿足⌊nt⌋=⌊ni⌋
而這篇的主旨便是要證明這件事。
證明分兩部份:
- 證明⌊nt⌋=⌊ni⌋
- 證明t為滿足該條件的上界,也就是證明⌊nt+1⌋≠⌊ni⌋
首先進行第一部份的證明。
n,m,k∈N+且⌊nk⌋=m,試證⌊n⌊nm⌋⌋=m:
(⌊nm⌋就相當於程式碼中的t、k相當於i)
1.
⌊nm⌋≤nm
m≤n⌊nm⌋
m=⌊m⌋≤⌊n⌊nm⌋⌋
2.
m=⌊nk⌋≤nk
mk≤n
k=⌊k⌋≤⌊nm⌋
nk≥n⌊nm⌋
m=⌊nk⌋≥⌊n⌊nm⌋⌋
由1.、2.,得證⌊n⌊nm⌋⌋=m
接著進行第二部份的證明。
n,m∈N+,試證⌊n⌊nm⌋+1⌋≠m:
nm<⌊nm⌋+1
n⌊nm⌋+1<m
⌊n⌊nm⌋+1⌋≤n⌊nm⌋+1<m
得證⌊n⌊nm⌋+1⌋≠m
沒有留言:
張貼留言