做水题的感觉真好系列
HDU 2084 数塔
1: 1
2: 1 2
3: 1 2 3
4: 1 2 3 4
5: 1 2 3 4 5
dp[i][j]第i行第j个数取得的最大值
dp[i][j] = max(dp[i-1][j-1], dp[i-1][j]) + a[i][j]。
代码:
/********************************************************* Problem : 2084 ( 数塔 ) Judge Status : Accepted RunId : 14525016 Language : G++ Author : G_lory Code Render Status : Rendered By HDOJ G++ Code Render Version 0.01 Beta **********************************************************/ #include <iostream> #include <cstdio> #include <algorithm> using namespace std; int a[105][105]; int dp[105][105]; int N; void solve() { for (int i = 1; i <= N; ++i) { for (int j = 1; j <= i; ++j) { dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - 1]) + a[i][j]; } } int ans = dp[N][1]; for (int i = 2; i <= N; ++i) { ans = max(ans, dp[N][i]); } printf("%d\n", ans); } int main() { int t; scanf("%d", &t); while (t--) { scanf("%d", &N); for (int i = 1; i <= N; ++i) for (int j = 1; j <= i; ++j) scanf("%d",&a[i][j]); solve(); } return 0; }
HDU 2044 一只小蜜蜂...
Fibonacci数列。
代码:
/********************************************************* Problem : 2044 ( 一只小蜜蜂... ) Judge Status : Accepted RunId : 14532121 Language : G++ Author : G_lory Code Render Status : Rendered By HDOJ G++ Code Render Version 0.01 Beta *********************************************************/ #include <iostream> #include <cstdio> using namespace std; typedef long long ll; ll dp[55]; void init() { dp[0] = dp[1] = 1; for (int i = 2; i <= 50; ++i) dp[i] = dp[i - 1] + dp[i - 2]; } int main() { init(); int t, a, b; scanf("%d", &t); while (t--) { scanf("%d%d", &a, &b); printf("%lld\n", dp[b - a]); } return 0; }
HDU 2041 超级楼梯
同上题。
代码:
/******************************************************** Problem : 2041 ( 超级楼梯 ) Judge Status : Accepted RunId : 14532404 Language : G++ Author : G_lory Code Render Status : Rendered By HDOJ G++ Code Render Version 0.01 Beta *********************************************************/ #include <iostream> #include <cstdio> using namespace std; typedef long long ll; ll dp[45]; void init() { dp[1] = dp[2] = 1; for (int i = 3; i <= 40; ++i) dp[i] = dp[i - 1] + dp[i - 2]; } int main() { init(); int t, a; scanf("%d", &t); while (t--) { scanf("%d", &a); printf("%lld\n", dp[a]); } return 0; }
HDU 2050 折线分割平面
一开始思路就错了,想的是一条直线最大的切割方法是把所有的面的切成两半,当然那是不可能的,最优的方法是把每条已有直线分成两段,这样该直线被已有直线分成已有直线条数+1的段,每一段把所在区域分成两半。
如果是折线,就把原有区域以最优的方式分解两次,注意两次方式相同,不能先分一次,在把第一部分的结果计算进去划第二次。因为是折线,在两条直线划分的基础上要连起来一端,所以少了1个区域。
dp[i] = dp[i-1]+((i-1)*2+1)*2-1; (我竟然忘了怎么通过递推公式求通项 = =……
(i-1)*2 原有直线(一条折线看成两条直线)条数。
((i-1)*2+1) 新加一条线段,被切割成多少分,也就是新加一条线段,多几个区域。
((i-1)*2+1)*2 因为是折线,相当于多加两条线段。
((i-1)*2+1)*2-1 折线会因为合并起来那一端减少一个区域。
代码:
/********************************************************* Problem : 2050 ( 折线分割平面 ) Judge Status : Accepted RunId : 14533258 Language : G++ Author : G_lory Code Render Status : Rendered By HDOJ G++ Code Render Version 0.01 Beta *********************************************************/ #include <iostream> #include <cstdio> using namespace std; int dp[10005]; void init() { dp[0] = 1; dp[1] = 2; for (int i = 2; i <= 10000; ++i) { //dp[i] = dp[i - 1] + ((i - 1) * 2 + 1) * 2 - 1; dp[i] = dp[i - 1] + 4 * i - 3; } } int main() { int t, n; init(); scanf("%d", &t); while (t--) { scanf("%d", &n); printf("%d\n", dp[n]); } return 0; }