C++ 高精演算法
阿新 • • 發佈:2018-12-30
高精演算法這東西聽起來還是有點高大上,說白了就是模擬小學學的豎式加減乘除,原理非常的簡單,用一個int陣列儲存一個數,int陣列中每一個表示這個數的每一位,陣列中的順序是從低位到高位儲存,這樣在運算的時候進退位很方便,並且用陣列中第一個記錄這個數的長度,這樣就避免判斷高位0是否是有效0。還有就是處理運算後進退位造成的位數長度變化,這個需要點技巧,我是最開始讓結果位長度等於原位長度,然後在進位到最高位的時候再增加位長度。從我提交上去的結果也可以看出,除了那些用i128沒用高精的,比較其他用高精的,效率還是算很高的了。所以說高精的處理很需要技巧,也許還有很多比我更優秀的
由於解題只用到了乘和加,所以程式碼中我也只寫了乘和加,減和除可根據原理寫出類似的程式碼
#include<iostream> #include<memory.h> using namespace std; struct hint{ int b[100]; }; void mul(hint* a1,int a2,hint* ret){ for(int i=1;i<=a1->b[0];++i){ ret->b[i]=a1->b[i]*a2; } int h=a1->b[0]; for(int i=1;i<=h;++i){ if(ret->b[i]/10>0){ ret->b[i+1]+=ret->b[i]/10; ret->b[i]=ret->b[i]%10; if(i==h){ ++h; } } } ret->b[0]=h; } void add(hint* a1,hint* a2){ int l=a1->b[0]<a2->b[0]?a2->b[0]:a1->b[0]; for(int i=1;i<=l;++i){ a1->b[i]+=a2->b[i]; } for(int i=1;i<=l;++i){ if(a1->b[i]/10>0){ a1->b[i+1]+=a1->b[i]/10; a1->b[i]=a1->b[i]%10; if(i==l){ ++l; } } } a1->b[0]=l; } hint* max(hint* a1,hint* a2){ if(a1->b[0]>a2->b[0]){ return a1; } else if(a1->b[0]<a2->b[0]){ return a2; } else{ for(int i=a1->b[0];i>=1;--i){ if(a1->b[i]<a2->b[i]){ return a2; } else if(a1->b[i]>a2->b[i]){ return a1; } } } return a1; } void show(hint* val){ for(int i=val->b[0];i>=1;i--){ cout<<val->b[i]; } } int main(){ int m,n; cin>>m>>n; int** matrix=new int*[m+1]; hint** dp=new hint*[n+2]; hint* base=new hint[n+1]; base[0].b[0]=1; base[0].b[1]=1; for(int i=1;i<=n;++i){ mul(&base[i-1],2,&base[i]); } for(int i=0;i<=m;++i){ matrix[i]=new int[n+1]{0}; } for(int i=0;i<=n+1;++i){ dp[i]=new hint[n+2]; memset(dp[i],0,sizeof(hint)*(n+2)); } for(int i=1;i<=m;++i){ for(int j=1;j<=n;++j){ cin>>matrix[i][j]; } } hint* ret=new hint; ret->b[0]=0; ret->b[1]=0; for(int i=1;i<=m;++i){ hint* val=0; int st=0; int ed=0; int step=0; for(int j=1;j<=n+1;++j){ for(int k=1;k<=n-j+2;++k){ hint t1; hint t2; memset(&t1,0,sizeof(hint)); memset(&t2,0,sizeof(hint)); mul(&base[step],matrix[i][ed],&t1); mul(&base[step],matrix[i][st],&t2); add(&t1,&dp[j-1][k]); add(&t2,&dp[j][k-1]); if(max(&t1,&t2)==&t1){ dp[j][k]=t1; } else{ dp[j][k]=t2; } if(val!=0&&max(&dp[j][k],val)==val){ } else{ val=&dp[j][k]; } st++; step++; } ed=ed==0?n:ed-1; step=j; st=0; } add(ret,val); } show(ret); }