【Luogu】【关卡2-12】递推与递归二分(2017年10月)

任务说明:递推,层层递进,由基础推向顶层。二分不仅可以用来查找数据,还可以确定最合适的值。

P1192 台阶问题

有N级的台阶,你一开始在底部,每次可以向上迈最多K级台阶(最少1级),问到达第N级台阶有多少种不同方式。

输入文件的仅包含两个正整数N,K。

输入文件stair.out仅包括1个正整数,为不同方式数,由于答案可能很大,你需要输出mod 100003后的结果。

解答: 我自己写的时间复杂度是O(N^2), 空间复杂度是O(K);看了题解还有用前缀和方法O(N)的...真厉害

提交了一次AC了

 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 }
View Code

数的划分  

传球游戏  

奇怪的电梯  

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])  //上面那些行

 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 }
View Code

数列分段Section II  

丢瓶盖

原文地址:https://www.cnblogs.com/zhangwanying/p/7637021.html