任务说明:递推,层层递进,由基础推向顶层。二分不仅可以用来查找数据,还可以确定最合适的值。
P1192 台阶问题
有N级的台阶,你一开始在底部,每次可以向上迈最多K级台阶(最少1级),问到达第N级台阶有多少种不同方式。
输入文件的仅包含两个正整数N,K。
输入文件stair.out仅包括1个正整数,为不同方式数,由于答案可能很大,你需要输出mod 100003后的结果。
解答: 我自己写的时间复杂度是O(N^2), 空间复杂度是O(K);看了题解还有用前缀和方法O(N)的...真厉害
提交了一次AC了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 void print(vector<int> dp, string strName) { 6 printf("======begin=====debug=====name[%s]====== ", strName.c_str()); 7 for (int i = 0; i < dp.size(); ++i) { 8 printf("%d ", dp[i]); 9 } 10 printf(" "); 11 } 12 13 int solve(int n, int k) { 14 vector<int> dp(n, 0); 15 for (int i = 0; i < n; ++i) { 16 if (i < k) { dp[i] = 1; } 17 for (int j = i-1; j >= 0 && j >= i - k; --j) { 18 dp[i] += dp[j]; 19 } 20 } 21 //print(dp, "another method"); 22 return dp[n-1]; 23 } 24 25 //这里时间复杂度是O(N^2), 空间复杂度是O(K); 26 //看了题解还有用前缀和方法O(N)的...真厉害 27 int main() { 28 int n, k; 29 cin >> n >> k; 30 vector<int> dp(k, 1); 31 int cnt = 2; 32 int idx; 33 while(cnt <= n) { 34 idx = (cnt - 1) % k; 35 int summ = 0; 36 //相当于下面两堆.. 37 //本质问题在于:第一遍初始化dp数组的时候,比如n=5, k=3, dp[0] =1,dp[1]=2, dp[2]=4; 其实这不是用所有的加起来,而是只加前面的那堆。 38 for (int i = 0; i < min(cnt, k); ++i) { 39 summ += dp[i]; 40 summ %= 100003; 41 } 42 /* 43 if (cnt < k) { 44 for (int i = 0; i < cnt; ++i) { 45 summ += dp[i]; 46 } 47 48 } else { 49 for (int i = 0; i < k; ++i) { 50 summ += dp[i]; 51 } 52 } 53 */ 54 dp[idx] = summ % 100003; 55 56 cnt++; 57 } 58 cout << dp[idx] << endl; 59 //int answer = solve(n, k); 60 //printf("another slover: %d ", answer); 61 return 0; 62 }
数的划分
传球游戏
奇怪的电梯
P1216 [USACO1.5]数字三角形 Number Triangles
没错就是你想的那道题~
解答:
转移方程为:
tri[i][j] = tri[i][j] (i == N-1) //最后一行
tri[i][j] += max(tri[i+1][j], tri[i+1][j+1]) //上面那些行
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 int main() { 6 int lines; 7 cin >> lines; 8 int tri[lines][lines] = {0}; 9 for (int i = 0; i < lines; ++i) { 10 for (int j = 0; j < i+1; ++j) { //写代码的时候注意下i, j的范围 11 cin >> tri[i][j]; 12 } 13 } 14 15 for (int i = lines - 2; i >= 0; --i) { 16 for (int j = 0; j <= i; ++j) { 17 tri[i][j] += max(tri[i+1][j], tri[i+1][j+1]); 18 } 19 } 20 21 cout << tri[0][0] << endl; 22 23 return 0; 24 }
数列分段Section II
丢瓶盖