请问计算出你可以采用多少种不同的方式爬完这个楼梯(到最后一层为爬完)。
(注意超大数据)
def matmul(A, B): C = [[0, 0, 0], [0, 0, 0], [0, 0, 0]] for i in range(3): for j in range(3): for k in range(3): C[i][j] += (A[i][k] * B[k][j]) return C def mat_power(A, count): B = [[1, 0, 0], [0, 1, 0], [0, 0, 1]] while (count > 0) : if count % 2 == 1: B = matmul(B, A) A = matmul(A, A) count //= 2 return B def work(): n = int(input()) f = [0 for i in range(n + 1)] f[0] = f[1] = f[2] = 1 f[3] = 2 if n <= 3: print(f[n]) return A = [[f[2], f[0], f[1]], [f[3], f[1], f[2]], [0, 0, 0]] B = [[1, 0, 1], [1, 0, 0], [0, 1, 0]] count = n - 2 - n % 2 B = mat_power(B, count) B = matmul(A, B) if n % 2 == 1: print(B[1][0]) else: print(B[0][0]) work()
import java.io.BufferedReader; import java.io.InputStreamReader; import java.math.BigInteger; public class Main { public static void main(String[] args) throws Exception{ BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int n = Integer.parseInt(br.readLine()); BigInteger[] count = new BigInteger[n]; count[0] = new BigInteger("1"); count[1] = new BigInteger("1"); count[2] = new BigInteger("2"); for (int i = 3; i < n; i++) { count[i] = count[i - 1].add(count[i - 3]); } System.out.println(count[n - 1]); } }
#include<bits/stdc++.h> using namespace std; string jiafa(string a,string b) { int cdc=a.length()-b.length(),jw=0; string ans;ans.resize(cdc>0?a.length():b.length()); if(cdc>=0) for(int i=0;i<cdc;i++) b='0'+b; else for(int i=0;i>cdc;i--) a='0'+a; for(int i=a.length()-1;i>=0;i--) { int m=a[i]-'0'+b[i]-'0'+jw; jw=m/10; ans[i]=m%10+'0'; } if(jw) ans='1'+ans; return ans; } int main() { int n;cin>>n; string f[500]={"1","1","1","2"}; for(int i=4;i<=n;i++) f[i]=jiafa(f[i-1],f[i-3]); cout<<f[n]<<endl; }愚蠢的我在做的时候还想,这题帖个动归标签是不是太糊弄了,其实是考大数运算的吧,结果看到PYTHON开挂的兄弟,还是怪我会的太少。。。
n = int(input()) steps = [0]*(n + 1) # 楼梯阶数小于等于2的时候只有一种爬法(一次爬一阶),阶数为3的时候有两种爬法(一次爬一阶或直接上三阶) steps[1], steps[2], steps[3] = 1, 1, 2 for i in range(4, n + 1): steps[i] = steps[i - 1] + steps[i - 3] # 可能是前1阶爬上来的,也可能是前3阶爬上来的 print(steps[-1])
import java.util.*; import java.math.*; public class Main{ static BigInteger func(int n){ BigInteger[] ll=new BigInteger[n+1]; ll[1]=new BigInteger("1"); ll[2]=new BigInteger("1"); ll[3]=new BigInteger("2"); for(int i=4;i<=n;i++){ ll[i]=ll[i-1].add(ll[i-3]); } return ll[n]; } public static void main(String[] args){ Scanner sc=new Scanner(System.in); int n=sc.nextInt(); System.out.println(func(n)); } }
/* *参考大佬的代码写的,在此处感谢 @夏夜飘雪 * 链接:https://www.nowcoder.com/questionTerminal/b178fcef3ed4448c99d7c0297312212d?f=discussion */ #include <iostream> #include <string> #include <vector> #include <algorithm> #include <limits.h> using namespace std; int main(){ int n; cin>>n; vector<vector<int>> dp(n+1, vector<int>(100, 0)); int len = 1; dp[1][0] = 1; dp[2][0] = 1; dp[3][0] = 2; for(int i=4; i<=n; i++) { for(int j=0; j<len; j++) { dp[i][j] += dp[i-1][j] + dp[i-3][j]; if(dp[i][j] > 9) { dp[i][j+1] += dp[i][j] / 10; dp[i][j] %= 10; len += (j == len-1); } } } for(int i =0; i < len; i++) { cout<<dp[n][len -1 -i]; } cout<<endl; return 0; }
DP + 高精度做法
#include <iostream> #include <vector> #include <algorithm> using namespace std; const int N = 510; vector<int> dp[N]; int n; vector<int> add(vector<int> a, vector<int> b) { vector<int> c; int t = 0; for (int i = 0; i < a.size() || i < b.size(); i ++) { if (i < a.size()) t += a[i]; if (i < b.size()) t += b[i]; c.push_back(t % 10); t /= 10; } if (t) c.push_back(t); return c; } int main() { cin >> n; dp[0] = vector<int> (1, 1); for (int i = 1; i <= n; i ++) { dp[i] = dp[i - 1]; if (i >= 3) dp[i] = add(dp[i], dp[i - 3]); } for (int i = dp[n].size() - 1; i >= 0; i --) cout << dp[n][i]; return 0; }
#include <bits/stdc++.h> using namespace std; string addstr(string str1,string str2){ string &longstr=str1.size()>=str2.size()? str1:str2; string &shortstr=str1.size()<str2.size()? str1:str2; string sum; shortstr.insert(0,longstr.size()-shortstr.size(),'0');//对齐位数 sum.resize(str1.size()+str2.size()); //预留空间 int up=0,i=shortstr.size()-1,j=longstr.size()-1,k=sum.size()-1; while(i>=0){ int temp=shortstr[i--]-'0'+longstr[j--]-'0'; sum[k--]=(temp+up)%10+'0'; //只保存个位 up=(temp+up)/10; //保存进位 } if(up!=0) sum[k--]=up+'0'; sum=sum.substr(k+1); return sum; } int main(){ int n; cin>>n; vector<string> dp; dp.resize(n+1); dp[0]=dp[1]=dp[2]="1"; for(int i=3;i<=n;i++){ dp[i]=addstr(dp[i-1],dp[i-3]); cout<<dp[i]<<endl; } cout<<dp[n]; }
import sys def diffroad(n): # n<3 索引位置:n-1 # n>=3 索引位置:(n-1)%3 res = [1,1,2] if n<3: return 1 if n==3: return 2 # f(n) = f(n-1)+f(n-3) for i in range(4,n+1): res[(i-1)%3] += res[(i+1)%3] return res[(n-1)%3] if __name__=="__main__": n = int(sys.stdin.readline().strip()) print(diffroad(n))
import sys try: while True: line = sys.stdin.readline().strip() if line == '': break n=int(line) if 100<=n<500: sum=0 for i in range(1,n//3): res=1 for j in range(2*i,3*i): res*=(n-j) for k in range(1,i+1): res//=k sum+=res if n%3==0: sum+=2 elif n%3==1: sum+=n//3+2 else: res=1 for i in range(1,n//3+1): res=res*(n//3+3-i)//i sum+=res+1 print(sum) except: pass
line = input() if line == '': print(None) n = int(line) if 100 <= n < 500: a = [1, 1, 2] for _ in range(n-3): a = [a[1], a[2], a[0] + a[2]] print(a[2])
#include<bits/stdc++.h> using namespace std; string dp[500]; // dp,用字符串就好 string add(string a,string b) { while(a.size()<b.size()) a = '0' + a; while(b.size()<a.size()) b = '0' + b; int len = a.size(); int carry = 0; string res = ""; for(int i=len-1;i>=0;i--) { int temp = carry + a[i] - '0' + b[i] - '0'; res = to_string(temp%10) + res; carry = temp/10; } while(carry) { res = to_string(carry%10) + res; carry/=10; } return res; } int main() { //memset(dp,0,sizeof(dp)); dp[0]="1"; dp[1]="1"; dp[2]="1"; int n; cin>>n; for(int i=3;i<=n;i++) dp[i]=add(dp[i-3],dp[i-1]); cout<<dp[n]<<endl; return 0; }
n = int(input()) res = [0]*(n+1) res[1],res[2],res[3] = 1,1,2 for i in range(4,n+1): res[i] = res[i-1]+res[i-3] print(res[n])
class MainActivity: def main(self): # Read the data n = int(input()) # Initialization schemes = [1, 1, 2] if n < 4: print(schemes[n - 1]) return # Traverse for _ in range(n - 3): schemes.append(schemes[0] + schemes[-1]) schemes.pop(0) print(schemes[-1]) if __name__ == '__main__': M = MainActivity() M.main()
data = [0 for n in range(500)] def getWays(stairs): if stairs <= 2: return 1 if stairs == 3: return 2 if data[stairs - 1] == 0: data[stairs - 1] = getWays(stairs - 1) if data[stairs - 3] == 0: data[stairs - 3] = getWays(stairs - 3) step1 = data[stairs - 1] step3 = data[stairs - 3] return step1 + step3; num = int(input()) print(str(getWays(num)))
import java.util.*; import java.math.*; public class Main{ public static void main(String[] args){ Scanner sc = new Scanner(System.in); int n = sc.nextInt(); //为什么要三个,因为n阶楼梯,只和前三个相关,也就是我后面的只要存住当前位置的前三个数,那么后面需要的时候还能取到。 BigInteger dp1 = new BigInteger("1"); BigInteger dp2 = new BigInteger("1"); BigInteger dp3 = new BigInteger("1"); Map<Integer,BigInteger> map = new HashMap<>(); map.put(1,dp1); map.put(2,dp2); map.put(3,dp3); for(int i=4;i<=n;i++){ //将当前位置的前三阶的数量加上当前位置的前一阶的数量 BigInteger dp4 = new BigInteger("0"); BigInteger dp5 = new BigInteger("0"); dp4=dp4.add(map.get(i-1)); dp5=dp5.add(map.get(i-3)); map.put(i,dp4.add(dp5)); } System.out.println(map.get(n)); }hashmap模拟dp表为什么不能通过?有没有大佬解释一下