迭代法 习题集
例題一 兔子繁殖問題
一對兔子從出生后第三個月開始,每月生一對小兔子。小兔子到第三個月又開始生下一代小兔子假若兔子只生不死,一月份抱來一對剛出生的小兔子,問一年中指定月份有多少對兔子? 分析:? ? ? ? 一月份有1對,二月份也是1對,三月份2對(新出生一對),四月份3對,五月份5對...... ????????
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
| 1 | 1 | 2 | 3 | 5 | 8 | . | . | . | . | . | (n-1)+(n-2) |
即為斐波那鍥數列求和問題。根據問題有迭代公式? f(n)=f(n-1)+f(n-2),初始條件 f(1)=1; f(2)=1;
第一種解決方法:
#include<iostream> using namespace std; int main(){int n;cin>>n;int f[12];f[0]=1;f[1]=2;if(n<2){cout<<1<<endl;return 0;}for(int i=2;i<n;i++){f[i]=f[i-1]+f[i-2];}cout<<f[n-1]<<endl;return 0; }這種解決方法可以把n個月的結果都計算并保存下來,時間復雜度為O(n),空間復雜度也為O(n)
第二種解決方法:
用A代替 f(n-1),B代替 f(n-2),C代替 f(n),可減少空間開銷,空間復雜度為O(1),時間復雜度仍為O(n)
#include<iostream> using namespace std; int main(){int n;cin>>n;int A=1,B=1;int C;if(n<3){cout<<1<<endl;return 0;}for(int i=3;i<=n;i++){C=A+B;A=B;B=C;}cout<<C<<endl;return 0; }例題二? 數組a[n]構造b[n]
給定一數組a[N],我們希望構造數組b [N],其中b[j]=a[0]*a[1]…a[N-1] / a[j],在構造過程中,不允 許使用除法;要求O(1) 空間復雜度和O(n) 的時間復雜度 分析:? ? ? ? ?假設N=5,即a[5]={a0,a1,a2,a3,a4},根據題干中給出的b[n]的公式可得:
| i | 0 | 1 | 2 | 3 | 4 |
| b[i] | a1*a2*a3*a4 | a0*a2*a3*a4 | a0*a1*a3*a4 | a0*a1*a2*a4 | a0*a1*a2*a3 |
代碼一:
#include<iostream> #define MAX 1000 using namespace std; int main(){int a[MAX],b[MAX]={1};for(int i=0;i<n;i++)cin>>a[i];for(int i=0;i<n;i++){for(int j=0;j<n;j++){if(j!=i){b[i]*=a[j];}}}for(int i=0;i<n;i++){cout<<b[i]<<" ";cout<<endl;return 0; }雖然滿足不使用除法,但算法中時間復雜度為O()空間復雜度為O(n)不符合題意;
改進1:由表格中的數據可知,每個b[i]都可以根據下標分為大于 i 和小于 i的兩個部分,如:b[0]=1*a[1]*a[2]*a[3]*a[4],b[2] =a[0]*a[1]*a[3]*a[4], b[3]=a[0]*a[1]*a[2]*a[4],以此可將b[i]轉換成兩個部分的積:
left[i]=a[0]*a[1]*...*a[i-1];
right[i]=a[i+1]*a[i+2]*...*a[n];
b[i]=left[i]*right[i];
此時,計算left和right的時間復雜的均為O(n),空間復雜度為O(n),進一步可以將left[i]轉化:
left[i]=a[i-1]*left[i-1]; 同理:right[i]=a[i-1]*right[i+1];
改進后: #include<iostream> #define MAX 1000 using namespace std; int main(){int n;cin>>n;int left[MAX],right[MAX],b[MAX],a[MAX];for(int i=0;i<n;i++){cin>>a[i];}left[0]=1;right[n-1]=1;for(int i=1;i<n;i++){left[i]=a[i-1]*left[i-1];}for(int i=n-2;i>=0;i--){right[i]=a[i-1]*right[i+1];}for(int i=0;i<n;i++){b[i]=left[i]*right[i];}for(int i=0;i<n;i++)cout<<b[i];cout<<endl; return 0; }上述算法中空間復雜度為O(n),仍不滿足題目的要求,降低空間復雜度:
b[i]=a[i+1]*b[i+1]; ????????????????temp=a[i];? ? ? ?a[i]=temp*a[i-1];????????????????b[i]=b[i]*a[i];
其中b[n-1]=1;此時空間復雜度滿足條件為O(1);
最終代碼:
#include<iostream> #define max 1000 using namespace std; int main(){int n,temp;int a[max],b[max];cin>>n;for(int i=0;i<n;i++)cin>>a[i];b[n-1]=1;for(int i=n-2;i>=0;i--){b[i]=a[i+1]*b[i+1];}temp=a[0];a[0]=1;for(int i=1;i<n;i++){a[i]=temp*a[i-1];temp=a[i];}for(int i=0;i<n;i++){b[i]=b[i]*a[i];cout<<b[i];}cout<<endl; return 0; }例三 求最大公約數?
求兩個數的最大公約數,給定兩個整數a,b,求最大的正整數c,使得c|a,c|b(c|a 表示c整除a)
輾轉相除法
#include<iostream> using namespace std; int GCD(int a,int b){int c; if(a<b){int temp;temp=a;a=b;b=temp;}while(b!=0){c=b;b=a%b;a=c;}return c; } int main(){int a,b;cin>>a,b;int C;C=GCD(a.b);cout<<C<<endl; return 0; }總結
- 上一篇: 通才与专才之辩 | 享受工作系列
- 下一篇: 仙剑5手游服务器维护,仙剑奇侠传手游5月