动态规划

匿名 (未验证) 提交于 2019-12-02 23:30:02

斐波那契数列

F【0】、F【1】……F【N】   ->状态

书写代码方法:

顺着推/逆着推/记忆化搜索

代码示例:

#include<iostream> using namespace std;  int n,f[10086];  int main(){          /*      *顺着推      */      cin>>n;     f[0]=1;     f[1]=1;          for( int i=2 ; i<=n ; ++i ){         f[i]=f[i-1]+f[i-2];     }          cout<<f[n];          /*      *逆着推      */      cin>>n;     f[0]=1;     f[1]=1;          for( int i=0 ; i<n ; ++i ){         f[i-1] += f[i];         f[i-2] += f[i];     }          cout<<f[n];          return 0; } 

记忆化搜索:

#include<iostream> using namespace std; #define N 10086  int n; int f[N]; bool vis[N];  /*  *搜索  */  int dfs( int n ){          if( n==0 ) return 1;     if( n==1 ) return 1;          return dfs(n-1)+dfs(n-2); }//O( f(n) )  /*  *记忆化搜索   */ int dfs( int n ){          if( n==0 ) return 1;     if( n==1 ) return 1;     if( vis(n) ) return f[n];          vis[n] = 1;     f[n] = dfs(n-1)+dfs(n-2);          return f[n]; }//O(n)   int main(){          cin>>n;     cout<<dfs(n)<<endl;          return 0; }

常见动态规划种类:

数位/树形/状压/区间/其他

(插头/博弈论)

数位DP:

读入两个正整数,L,R ,在【L,R】中,有多少个数?

[L~R] -> [0~R] - [0~(L-1)]

[0,X] -> Xn Xn-1 Xn-2 ...... Xn-n
0<=V<=X -> Vn Vn-1 Vn-2 ...... Vn-n

1、 XnXn-1Xn-2 > VnVn-1Vn-2 Vn∈[0,9];
2、 XnXn-1Xn-2 = VnVn-1Vn-2 Vn∈[0,Xn];

״̬
f[i][j] -> 该状态方案数
i -> 已填好的第i位
j -> 0/1 j=0 XnXn-1Xn-2 > VnVn-1Vn-2
j=1 XnXn-1Xn-2 = VnVn-1Vn-2

转移方程
枚举i-1位填什么
f[i][j]=f[i-1][j]

边界
Xn+1 = 0 ; Vn+1 = 0

#include<iostream> using namespace std; #define N 10086  int l,r,z[N]; int f[N][2];  int solve( int x ){     int n=0;     while(x){         z[n] = x%10;         x/=10;         n++;     }     n--;          memset( f,0,sizeof(f));     f[n+1][1] = 1;          for( int i=n ; i>=0 ; --i ){         for( int j=0 ; j<=1 ; ++j ){             if( b==0 ){                 for( int k=0 ; k<=9 ; ++k ){                     f[i][0] += f[i+1][0];                 }             }             else{                 for(int k=0 ; k<=z[a] ; ++k ){                     if( k==z[a] ) f[a][1] += f[a+1][1];                     else f[a][0] += f[a+1][1];                 }             }         }     }          return f[0][0] + f[0][1]; }  int main(){      cin>>l>>r;          cout<< solve(r) - solve(l-1) <<endl;     return 0; }

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!