段誉身具凌波微波,动无常则,若危若安,一次能走一级台阶或者两级台阶,他要爬一段30级的山路,问有多少种走法?分析如何计算,然后编程解答。
进阶问题:当他轻功熟练度提升,一次最多可以走三级,那就结果有什么变化?后来走火入魔了,不能走一级,只能走二或三级,又有什么变化?
输入一个数n(1<=n<=30),代表段誉要爬一段n级的山路。
输出三个整数a,b,c(以空格相间)。其中a为段誉一次能走一级或两级台阶的走法;b为段誉一次能走一级、二级或三级台阶的走法;c为段誉一次能走二级或三级台阶的走法。
3
3 4 1
#include<bits/stdc++.h> using namespace std; int main() { int n; cin>>n; //本题n较小,所以递归也可以,但如果n较大则会超时,所以通用解法为动态规划 vector<int>dp1(n+1),dp2(n+1),dp3(n+1); vector<int>res(3); if(n==1) {cout<<1<<" "<<1<<" "<< 0;return 0;} if(n==2){cout<<2<<" "<<2<<" "<<1;return 0;} //第一种情况 dp1[0]=1; dp1[1]=1; for(int i=2;i<=n;i++) { dp1[i]=dp1[i-1]+dp1[i-2]; } res[0]=dp1[n]; //第二种情况 dp2[0]=1; dp2[1]=1; dp2[2]=2; for(int i=3;i<=n;i++) { dp2[i]=dp2[i-1]+dp2[i-2]+dp2[i-3]; } res[1]=dp2[n]; //第三种情况 dp3[0]=0; dp3[1]=0; dp3[2]=1; dp3[3]=1; for(int i=4;i<=n;i++) { dp3[i]=dp3[i-2]+dp3[i-3]; } res[2]=dp3[n]; cout<<res[0]<<" "<<res[1]<<" "<<res[2]; return 0; }
#include <iostream> using namespace std; int L1(int num){ if(num==0) return 1; else if(num<0) return 0; return L1(num-1)+L1(num-2); } int L2(int num){ if(num==0) return 1; else if(num<0) return 0; return L2(num-1)+L2(num-2)+L2(num-3); } int L3(int num){ if(num==0) return 1; else if(num<0) return 0; else return L3(num-3)+L3(num-2); } int main(){ int n; cin>>n; cout<<L1(n)<<" "<<L2(n)<<" "<<L3(n); system("pause"); return 0; }
#include <iostream> #include <string.h> using namespace std; int dfs1(int num){ if(num == 0) return 1; if(num < 0) return 0; return dfs1(num - 1) + dfs1(num - 2); } int dfs2(int num){ if(num == 0) return 1; if(num < 0) return 0; return dfs2(num - 1) + dfs2(num - 2) + dfs2(num - 3); } int dfs3(int num){ if(num == 0) return 1; if(num < 0) return 0; return dfs3(num - 2) + dfs3(num - 3); } int main() { int n, a, b, c; cin >> n; a = dfs1(n); b = dfs2(n); c = dfs3(n); cout << a << ' ' << b << ' ' << c << endl; return 0; }
const readline = require('readline') const rl = readline.createInterface({ input: process.stdin, ouput: process.stdout }) let inArr = [] rl.on('line', line=>{ if(!line) return inArr.push(line.trim()) if(inArr.length === 1){ let n = +inArr[0] let res = [dp1(n),dp2(n),dp3(n)] console.log(res.join(' ')) } }) function dp1(n){ let dp = [1,1,2] for (let i = 3; i < n+1; i++) { dp[i] = dp[i-1]+dp[i-2] } return dp[n] } function dp2(n){ let dp = [1,1,2,4] for (let i = 4; i < n+1; i++) { dp[i] = dp[i-1]+dp[i-2]+dp[i-3] } return dp[n] } function dp3(n){ let dp = [0,0,1,1] for (let i = 4; i < n+1; i++) { dp[i] = dp[i-3]+dp[i-2] } return dp[n] }
#include <bits/stdc++.h> using namespace std; int main() { int dp[3][50]; int n;cin >> n; dp[0][0]=dp[1][0]=dp[2][0]=1; for(int i=1;i<=n;i++) { dp[0][i]=((i-1>=0)?dp[0][i-1]:0)+((i-2>=0)?dp[0][i-2]:0); dp[1][i]=((i-1)>=0?dp[1][i-1]:0)+((i-2>=0)?dp[1][i-2]:0)+((i-3>=0)?dp[1][i-3]:0); dp[2][i]=((i-3>=0)?dp[2][i-3]:0)+((i-2>=0)?dp[2][i-2]:0); } cout << dp[0][n] << " " << dp[1][n] << " " << dp[2][n] << endl; }比较简短的线性DP代码
using System; public class Program{ public static void Main(){ int n = Convert.ToInt32(Console.ReadLine()); int[] dp_a = new int[n + 1]; int[] dp_b = new int[n + 1]; int[] dp_c = new int[n + 1]; Console.Write(StepOneAndTwo(n, dp_a) + " " + StepOneTwoThree(n, dp_b) + " " + StepTwoThree(n, dp_c)); } //走一步和兩步 public static int StepOneAndTwo(int stepLeft, int[] dp) { if(stepLeft < 0) { return 0; } if(stepLeft == 0) { return 1; } if(dp[stepLeft] != 0) { return dp[stepLeft]; } int result = StepOneAndTwo(stepLeft - 1, dp) + StepOneAndTwo(stepLeft - 2, dp); dp[stepLeft] = result; return dp[stepLeft]; } //走一、二、三步 public static int StepOneTwoThree(int stepLeft, int[] dp) { if(stepLeft < 0) { return 0; } if(stepLeft == 0) { return 1; } if(dp[stepLeft] != 0) { return dp[stepLeft]; } int result = StepOneTwoThree(stepLeft - 1, dp) + StepOneTwoThree(stepLeft - 2, dp) + StepOneTwoThree(stepLeft - 3, dp); dp[stepLeft] = result; return dp[stepLeft]; } //走兩步、三步 public static int StepTwoThree(int stepLeft, int[] dp) { if(stepLeft < 0) { return 0; } if(stepLeft == 0) { return 1; } if(dp[stepLeft] != 0) { return dp[stepLeft]; } int result = StepTwoThree(stepLeft - 2, dp) + StepTwoThree(stepLeft - 3, dp); dp[stepLeft] = result; return dp[stepLeft]; } }
#include<iostream> #include<vector> using namespace std; int main(){ int n , a, b, c; cin>>n; vector<int> dp1(n + 1, 0); vector<int> dp2(n + 1, 0); vector<int> dp3(n + 1, 0); //初始化 dp1[1] = 1 ,dp1[2] = 2; dp2[1] = 1 ,dp2[2] = 2, dp2[3] = 4; dp3[1] = 0 ,dp3[2] = 1, dp3[3] = 1; //思想,dp[i] = dp[i-1]+d[i-2]; if(n <= 2){ a = dp1[n]; b = dp2[n]; c = dp3[n]; } else{ for(int i = 3; i <= n ; i++){ dp1[i] = dp1[i - 1] + dp1[i -2]; } a = dp1[n]; for(int i = 4; i <= n; i++){ dp2[i] = dp2[i - 1] + dp2[i -2] + dp2[i -3]; } b = dp2[n]; for(int i = 4; i <= n; i++){ dp3[i] = dp3[i - 2] + dp3[i - 3]; } c = dp3[n]; } cout<< a << " "<< b << " "<< c; return 0; }
// 递归加记忆化搜索剪枝,改一改就是动态规划了 using System; using System.Collections; using System.Collections.Generic; public class Program { public static void Main() { string line = System.Console.ReadLine (); int a = int.Parse(line); if (a == 1) { Console.WriteLine("1 1 0"); } else { Console.WriteLine( $"{dpsOne(a,new Dictionary<int,int>())} {dpsTwo(a,new Dictionary<int,int>())} {dpsThree(a,new Dictionary<int,int>())}"); } } private static int dpsOne(int stage, Dictionary<int, int> dic) { if (dic.ContainsKey(stage))return dic[stage]; if (stage == 1 || stage == 2) return stage; int stage_1 = dpsOne(stage - 1, dic); if (!dic.ContainsKey(stage - 1)) { dic.Add(stage - 1, stage_1); } int stage_2 = dpsOne(stage - 2, dic); if (!dic.ContainsKey(stage - 2)) { dic.Add(stage - 2, stage_2); } return dic[stage - 1] + dic[stage - 2]; } private static int dpsTwo(int stage, Dictionary<int, int> dic) { if (dic.ContainsKey(stage))return dic[stage]; if (stage == 1 || stage == 2) return stage; if (stage == 3) return 4; int stage_1 = dpsTwo(stage - 1, dic); if (!dic.ContainsKey(stage - 1)) { dic.Add(stage - 1, stage_1); } int stage_2 = dpsTwo(stage - 2, dic); if (!dic.ContainsKey(stage - 2)) { dic.Add(stage - 2, stage_2); } int stage_3 = dpsTwo(stage - 3, dic); if (!dic.ContainsKey(stage - 3)) { dic.Add(stage - 3, stage_3); } return dic[stage - 1] + dic[stage - 2] + dic[stage - 3]; } private static int dpsThree(int stage, Dictionary<int, int> dic) { if (dic.ContainsKey(stage))return dic[stage]; if (stage == 2 || stage == 3 || stage == 4) return 1; int stage_2 = dpsThree(stage - 2, dic); if (!dic.ContainsKey(stage - 2)) { dic.Add(stage - 2, stage_2); } int stage_3 = dpsThree(stage - 3, dic); if (!dic.ContainsKey(stage - 3)) { dic.Add(stage - 3, stage_3); } return dic[stage - 2] + dic[stage - 3]; } }
import java.util.*; import java.io.*; public class Main{//青蛙跳台阶的翻版 public static void main(String []args)throws IOException{ BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); int n=Integer.parseInt(br.readLine()); if(n==1){ System.out.print("1 1 0"); return; } if(n==2){ System.out.print("2 2 1"); return; } if(n==3){ System.out.print("3 4 1"); return; } int[] nums_1=new int[n],nums_2=new int[n],nums_3=new int[n]; nums_1[0]=1;nums_1[1]=2;nums_1[2]=3; nums_2[0]=1;nums_2[1]=2;nums_2[2]=4; nums_3[0]=0;nums_3[1]=1;nums_3[2]=1; for(int i=3;i<n;i++){ nums_1[i]=nums_1[i-1]+nums_1[i-2]; nums_2[i]=nums_2[i-1]+nums_2[i-2]+nums_2[i-3]; nums_3[i]=nums_3[i-3]+nums_3[i-2]; } System.out.println(nums_1[n-1]+" "+nums_2[n-1]+" "+nums_3[n-1]); } }
#include<iostream> using namespace std; int ways[3]={0,0,0};//统计三种轻功的走法数量 void backTrace(int x,int n,int type,int *qingong){ //x=走到第几个阶梯,n=拢共有多少层阶梯,type=段誉只会第几种轻功, qingong=***详情 if(x==n){//登顶了 ways[type]++;//记录一下走法数量 return ; } //轻功有几种跨阶梯方式 int size =2; if(type==1) size+=1; for(int i=0;i<size;++i){ if(x+qingong[i]>n) continue;//不作无用功 backTrace(x+qingong[i],n,type,qingong);//没登顶,继续施展轻功 } } int main(){ int n; cin>>n;//输入 //轻功***图谱 int a[2]={1,2}; int b[3]={1,2,3}; int c[2]={2,3}; //用上述几种轻功尝试登顶,并记录次数 backTrace(0,n,0,a); backTrace(0,n,1,b); backTrace(0,n,2,c); //输出 cout<<ways[0]<<" "<<ways[1]<<" "<<ways[2]<<endl; return 0; }
#include<iostream> #include<vector> using namespace std; int main() { int n; while (cin >> n) { vector<int> a(n + 1, 0); vector<int> b(n + 1, 0); vector<int> c(n + 1, 0); a[0] = b[0] = c[0] = 1; a[1] = b[1] = 1; c[1] = 0; if (n == 1) { cout << a[1] << ' ' << b[1] << ' ' << c[1] << endl; continue; } a[2] = a[1] + a[0]; b[2] = b[1] + b[0]; c[2] = c[0]; for (int i = 3; i <= n; i++) { a[i] = a[i - 1] + a[i - 2]; b[i] = b[i - 1] + b[i - 2] + b[i - 3]; c[i] = c[i - 2] + c[i - 3]; } cout << a[n] << ' ' << b[n] << ' ' << c[n] << endl; } return 0; }
import java.util.*; public class Main{ public static void main(String[] args){ Scanner sc = new Scanner(System.in); int n = sc.nextInt(); System.out.println(help1(n)+" "+help2(n)+" "+help3(n)); } private static int help1(int n){ if(n==1) return 1; if(n==2) return 2; int[] dp = new int[n+1]; dp[0] = 0; dp[1] = 1; dp[2] = 2; for(int i = 3;i<=n;i++){ dp[i] = dp[i-1] + dp[i-2]; } return dp[n]; } private static int help2(int n){ if(n==1) return 1; if(n==2) return 2; if(n==3) return 4; int[] dp = new int[n+1]; dp[0] = 0; dp[1] = 1; dp[2] = 2; dp[3] = 4; for(int i = 4;i<=n;i++){ dp[i] = dp[i-1] + dp[i-2] + dp[i-3]; } return dp[n]; } private static int help3(int n){ if(n==1) return 0; if(n==2) return 1; if(n==3) return 1; int[] dp = new int[n+1]; dp[0] = 0; dp[1] = 0; dp[2] = 1; dp[3] = 1; for(int i = 4;i<=n;i++){ dp[i] = dp[i-2] +dp[i-3]; } return dp[n]; } }
num = int(input()) ans_1 = [1,2,3,5] ans_2 = [1,2,4,7] ans_3 = [0,1,1,1] if num > 4: for i in range(num - 4): ans_1.append(ans_1[3 - 1 + i] + ans_1[3 - 0 + i]) ans_2.append(ans_2[3 - 2 + i] + ans_2[3 - 1 + i] + ans_2[3 - 0 + i]) ans_3.append(ans_3[3 - 2 + i] + ans_3[3 - 1 + i]) print(str(ans_1[num - 1])+' '+str(ans_2[num - 1])+' '+str(ans_3[num - 1]))