您的位置:首页 > 其它

简单递推 学到的一些皮毛,总结一下

2012-02-19 11:09 274 查看
本来是做DP专题的,但我觉得还是多试试从基础的递推开始训练。可能对Dp有多点帮助。做到最后也发现递推也是很精妙的啊!这些题目来自hdu。都是for beginner~~ 我觉得我还是踏实点的好~~ 继续努力~~
HDU 2044一只小蜜蜂...
f(n) = f(n-1) + f(n-2) ; Fibonacci 到 n 分别有两条路,n-1 和 n-2 。一般这些题要注意用long long 型的,这个让我WA了几次~~
#include <iostream>using namespace std;int main(){long long dp[51],i,j,n;dp[1] = 1;dp[2] = 2;for(i = 3;i < 51;i ++)dp[i] = dp[i-1] + dp[i - 2];while(cin>>n){while(n --){cin>>i>>j;cout<<dp[j-i]<<endl;}}return 0;}
HDU 2045不容易系列之(3)―― LELE的RPG难题
想像一下,如果你一开始不知道这题是递推题,我怎么去思考这道题?这题高中时是一种排列组合的题型。要学会用分情况和假设的思维方式来考虑递推问题。如果是分情况来看待这题,这题首尾颜色不一样的条件会使情况越分越多,并且可能导致不全面,所以要简化这题。进行假设,假设首尾颜色可以一样,那么就会豁然开朗。即3*2^(n-1)种。然后要剪除颜色一样的情况,颜色首尾一样就是f(n-1)的情况了。所以结果就是f(n)=3*2^(n-1) - f(n-1);
#include <iostream>using namespace std;int main(){long long  f[51],i,n,cot = 4;f[1] = 3;f[2] = 6;for(i = 3;i < 51;i ++){f[i] = 3*cot-f[i-1];cot*=2;}while(cin>>n)cout<<f<<endl;return 0;}
HDU 2046骨牌铺方格
递推题还有一种方法,就是枚举找规律,很明显,这题是Fibonacci。分情况来分析这道题,因为是加东西上去,那在n-1拍好的情况下+1.只有一种情况,发现还有一些情况没考虑到,在n-2的情况下+2,也只有一种情况,发现所有情况都考虑到了,得到方程。
#include <iostream>using namespace std;int main(){__int64 f[51];int i,n;f[0]=1;f[1]=1;f[2]=2;f[3]=3;for(i=4;i<51;i++){f[i]=f[i-1]+f[i-2];}while(cin>>n){printf("%I64d\n",f);}return 0;}
HDU 2047阿牛的EOF牛肉串
很明显这道题要分类出来讨论,分为结尾是 O的 f1 和 结尾不是 O的 f2。结尾不是 O 的种数 : (上一次结尾是 O 的 + 上一次结尾不是 O 的)* 2 ;即是:f2(n+1) = 2 * ( f1(n) + f2(n) ) 。然后很容易发现结尾是 O 的等于上一次结尾不是 O 的种数。 即 f1(n) = f2(n-1) 。也就是说:f2(n+1) = 2* ( f2(n-1) + f2(n)); f1(n+1) = f2(n); f1(1) = 1;f2(1) = 2;F(1) = 3; F(2) = 6;于是 F(n+1) = 2*(F(n-1) + F(n)) ;
#include <iostream>using namespace std;int main(){long long dp[50],i,n;dp[1] = 3;dp[2] = 8;for(i = 3;i < 41;i ++){dp[i] = 2*(dp[i-2] + dp[i-1]);}while(cin>>n){cout<<dp<<endl;}}
HDU 2048神、上帝以及老天爷
错排,F(n) 表示n 人错排种数。如果把第i 个数放在非原位 k 上,则有n-1种。 此时 k 位的数可有两种情况: 1、放在 i 上,则有 F(n-2) 种。 2、放在非 i 上,则有F(n-1)种。所以F(n) = (n-1) * (F(n-2) + F(n-1));
#include <iostream>#include <cstdio>using namespace std;int main(){int n,m,t,i;double M[34],N[34];double ans;M[1] = 0;M[2] = 1;N[0] = 1;N[1] = 1;N[2] = 2;for(i = 3;i < 34;i ++){M[i] = (i-1)*(M[i-1]+M[i-2]);N[i]=i*N[i-1];}cin>>t;while(t--){cin>>n;ans = double(M/N);//cout<<M<<" "<<N<<endl;printf("%.2lf%%\n",100*ans);}return 0;}
HDU 2049不容易系列之(4)――考新郎
也是错排。
#include <iostream>using namespace std;int main(){int n,m,t,i;long long M[34],N[34];M[1] = 0;M[2] = 1;N[0] = 1;N[1] = 1;N[2] = 2;for(i = 3;i < 34;i ++){M[i] = (i-1)*(M[i-1]+M[i-2]);N[i]=i*N[i-1];}cin>>t;while(t--){cin>>n>>m;cout<<M[m]*(N/N[m]/N[n-m])<<endl;}return 0;}
看来做递推就是找规律,分类,假设,有点创造性思维。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: