Update records
[1]2020.05.1611:02
1. Improve the content
text
Tips before observation
 This article is a review series, not very detailed
 Need to have some recursive recursion and search basis
Recurrence
preface
Although it is recursive, it is closely related to dynamic planning
(my dynamic planning can't even reach the level of popularization)
So, recursion is the simplest thing, but it's also the most difficult thing for beginners to understand
Why is it simple?
 Take this algorithm alone, and you will find that you can't say anything
Why is it hard to understand?
 When you combine it into a question, sometimes you will find that you can't even figure out your ideas
So let's talk about the topic here
Fibonacci series
Orientation: basic question / entry difficulty
Of course, I'm referring to the naked question here (your FFT + Fibonacci numbers list the big problems)
\(f[i]=f[i1]+f[i2]\)
Notice the boundary conditions
And then it's gone
There's nothing to say. Notice that \ (i1 \) and \ (i2 \) have been evaluated. Just think of using array to store them
#include<iostream> using namespace std; int a[1000100],num=0,in; int main(){ a[1]=1;a[2]=1;cin>>num; for(int i=3;i<1000002;i++) a[i]=(a[i1]+a[i2]) for(int i=0;i<num;i++){ cin>>in;cout<<a[in]<<"\n"; } }
Digit problem
Orientation: basic questions / Popularization  difficulty
This problem is still very simple to do, but the process is a little testing everyone
Among the two digits, those with odd number 3 are:
\(13,23,43,53,63,73,83,93\)
\(30,31,32,34,35,36,37,38,39\)
Then we observe that when 3 is not in the highest position, the quantity is multiplied by 8
 High order cannot be 0 or 3
Number multiplied by 9 at the highest level
 It can be 0 but not 3 when it is not the highest position
And so on, the number of odd 3 numbers in three digits is:
 Individual bit
\((103,113,123,143,153,163,173,183,193)\)
Total 9 × 8 = 72
 Ten
\((130,131,132,134,135,136,137,138,139)\)
Total 9 × 8 = 72
 Centenary
\((301,302,304,305,306...398,399)\)
10099 = 81 in total
 other
\((333)\)
1 in total
So the number of odd number 3 is 72 × 2 + 81 + 1 = 226
Define array \ (f[i][2] \):
 \(f[i][0] \) indicates the number of even 3 digits in the idigit
 \(f[i][1] \) indicates the number of odd 3 digits in the idigit
The dynamic transfer equation is:
\(f[i][0]=(f[i1][0]*9+f[i1][1])%12345\)
\(f[i][1]=(f[i1][1]*9+f[i1][0])%12345\)
Just multiply the highest order by 8
#include<iostream> using namespace std; int f[20001][2],n; int main(){ cin>>n;f[1][0]=9;f[1][1]=1; for(int i=2;i<n;i++){ f[i][0]=(f[i1][0]*9+f[i1][1])%12345; f[i][1]=(f[i1][1]*9+f[i1][0])%12345; } if(n!=1){ f[n][0]=f[n1][0]*8+f[n1][1]; f[n][1]=f[n1][1]*8+f[n1][0]; } cout<<f[n][0]%12345; }
Step on the grid
Orientation: exercises / popularization difficulty
The amount of code in this question is really very small, but it's still hard to think about this idea
A lot of people are confused that they can't walk again
But we just need to sweep in separate directions
Define \ (f[i][3] \)
 \(f[i][0] \) means step I goes up
 \(f[i][1] \) means step I goes to the left
 \(f[i][2] \) means step I goes to the right
#include<iostream> using namespace std; int n,f[25][3]; int main(){ cin>>n;f[1][0]=1;f[1][1]=1;f[1][2]=1; for(int i=2;i<=n;i++){ f[i][0]=f[i1][0]+f[i1][1]+f[i1][2]; f[i][1]=f[i1][0]+f[i1][1]; f[i][2]=f[i1][0]+f[i1][2]; } cout<<f[n][0]+f[n][1]+f[n][2]; //In the end, that's the answer }
Building primary schools in Mountainous Areas
Orientation: think / improve difficulty
This problem is relatively comprehensive. In terms of the dynamic rules, there are few codes but it is difficult to come up with them
Define \ (b[i][o] \) and \ (f[i][o] \)
\(b[i][o] \) indicates the distance from I to o if a primary school is built, I to all villages in o to this primary school, and
\(f[i][o] \) represents the optimal solution for the first I villages to build o primary schools
#include<iostream> #include<cmath> using namespace std; int n,m,a[501],mid,i,o,p; int b[501][501],f[501][501]; int main(){ cin>>n>>m; for(i=2;i<=n;i++){ cin>>a[i];a[i]+=a[i1]; } //Here we use prefix sum to find the distance between two points for(i=1;i<=n;i++){ for(o=i;o<=n;o++){ mid=(i+o)/2; for(p=i;p<=o;p++) b[i][o]+=abs(a[mid]a[p]); } } //Obviously, the midpoint between two points must be the minimum value of b[i][o] for(int i=0;i<=n;i++){ for(int o=0;o<=m;o++) f[i][o]=99999999; } //initialization f[0][0]=0; for(i=1;i<=n;i++){ for(o=1;o<=m;o++){ if(o>i){ f[i][o]=0;continue; } //There are more schools to be built than villages = > there are primary schools at the gate of each village = > the sum of distances is zero for(p=o1;p<i;p++) f[i][o]=min(f[i][o],f[p][o1]+b[p+1][i]); //Enumeration of the first i villages } } cout<<f[n][m]; //output }
recursion
In fact, recursion can be understood as another way of writing dynamic rules (it's only slower, it takes up more memory)
Count of numbers
Orientation: basic questions / Popularization  difficulty
This question is a (anti recursion) send experience question
Recursion idea: start from 1 on the left and add to n/2
Recursion of next step after adding
Recursion version timeout 1 ms
#include<cstdio> int n,num=1; inline void pan(int n){ for(int i=1;i<=(n>>1);++i){ num+=1;pan(i); } } int main(){ scanf("%d",&n); pan(n); printf("%d",num); }
Overtime is not very good, so we change it into a dynamic gauge
Sweep from 1 to n
Little proof:
 n the left side can only add a number smaller than half
 But the added number (because it's smaller than n) has been calculated before
 Just add it directly
 Pay attention to boundary conditions
It's the perfect AC when changing into a dynamic gauge
#include<iostream> using namespace std; long long int f[1002];int a; int main() { f[1]=1; for(int i=2;i<=1001;i++){ for(int o=1;o<=i/2;o++) f[i]+=f[o]; f[i]+=1; } cin>>a;cout<<f[a]; }
So if you can still use it, use it. Recursive TLE and MLE will make you unable to play
search
(the greatest contribution of this algorithm is to prove that recursion is not useless.)
Generally speaking, we will encounter many different situations at a decisionmaking point
There will be many different situations after choosing one
But there are boundaries and decision points are limited
Then violent recursion  search algorithm appears!!
Search is to go through everything
But time and memory will be very high
Sometimes, a series of metaphysical operations such as backtracking, pruning (interval dynamic gauge) are used
Horse walking day
Orientation: basic questions / popularization difficulty
There's nothing to say. Every step of expansion is enough
#include<iostream> using namespace std; int t,n,m,x,y,num; bool bl[101][101]; int sx[8]={2,1,1,2,2,1,1,2}; int sy[8]={1,2,2,1,1,2,2,1}; void pan(int x,int y,int s){ if(x<0y<0x>=ny>=m) return; if(s==n*m) num+=1; bl[x][y]=1; //This point has been temporarily marked for use in the next step for(int i=0;i<8;i++) if(!bl[x+sx[i]][y+sy[i]]) pan(x+sx[i],y+sy[i],s+1); //Core, expanding in 8 directions bl[x][y]=0; //This step is over. The mark is not used } int main(){ cin>>t; for(int i=0;i<t;i++){ num=0;cin>>n>>m>>x>>y; pan(x,y,1);cout<<num<<"\n"; } }
Word Chain
Orientation: exercises / popularization difficulty
To sort out the questions:

Use a word twice at most

Not all the words

Cannot contain

There should be as little overlap as possible
So it is a function to judge the length of overlapping parts
Just search once
#include<iostream> using namespace std; string a[50]; int n,cnt[50],num,maxn; char begin; int yn(int a,int b){ int ayn=1,al=(::a[a].length()); for(int i=al1;i>=0;i){ ayn=1; if((::a[a][i])==(::a[b][0])){ for(int o=i;o<al;o++){ if((::a[a][o])!=(::a[b][oi])){ ayn=0;break; } } if(ayn) return ali; } } return 0; } void fs(int wei,int l,int p){ if(l>maxn) maxn=l; for(int i=0;i<n;i++){ if(cnt[i]>=2) continue; int c=yn(wei,i); if(c&&(c!=a[wei].length()c!=a[i].length())){ cnt[i]+=1;fs(i,l+a[i].length()c,p+1);cnt[i]=1; } } } int main(){ cin>>n; for(int i=0;i<n;i++) cin>>a[i]; cin>>begin; for(int i=0;i<n;i++){ if(a[i][0]==begin){ cnt[i]+=1;fs(i,a[i].length(),1);cnt[i]=1; } } cout<<maxn; }
summary
 These three algorithms are related to each other and pay attention to balance during learning