您的位置:首页 > 其它

动态规划之HDU水题

2015-08-15 18:48 274 查看

做水题的感觉真好系列

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
[1];
for (int i = 2; i <= N; ++i) {
ans = max(ans, dp
[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
);
}
return 0;
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: