段誉身具凌波微波,动无常则,若危若安,一次能走一级台阶或者两级台阶,他要爬一段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;
} Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int [] a = new int [31];
a[1] = 1;a[2] =2;
int [] b = new int [31];
b[1]= 1;b[2] = 2; b[3] =4;
int [] c = new int [31];
c[2] = 1; c[3] =1;
for(int i =3 ; i<=n ;i++) {
a[i] = a[i-1]+a[i-2];
if(i>3) {
b[i] = b[i-1] + b[i-2] + b[i-3];
c[i] = c[i-2] + c[i-3];
}
}
System.out.println(a[n] +" " + b[n] +" "+ c[n]); 摸鱼过来 // 递归加记忆化搜索剪枝,改一改就是动态规划了
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]))