P1216 [USACO1.5][IOI1994]数字三角形 Number Triangles
# [USACO1.5][IOI1994]数字三角形 Number Triangles
## 题目描述
观察下面的数字金字塔。
写一个程序来查找从最高点到底部任意处结束的路径,使路径经过数字的和最大。每一步可以走到左下方的点也可以到达右下方的点。
```cpp
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
```
在上面的样例中,从 $7 \to 3 \to 8 \to 7 \to 5$ 的路径产生了最大
## 输入格式
第一个行一个正整数 $r$ ,表示行的数目。
后面每行为这个数字金字塔特定行包含的整数。
## 输出格式
单独的一行,包含那个可能得到的最大的和。
## 样例 #1
### 样例输入 #1
```
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
```
### 样例输出 #1
```
30
```
## 提示
【数据范围】
对于 $100\%$ 的数据,$1\le r \le 1000$,所有输入在 $[0,100]$ 范围内。
题目翻译来自NOCOW。
USACO Training Section 1.5
IOI1994 Day1T1
dp过程图解:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
int max(int x,int y)
{
return x>y?x:y;
}
int main()
{
int r,a[1005][1005]={0};
scanf("%d",&r);
//输入
for(int i=1;i<=r;i++)
{
for(int j=1;j<=i;j++)
{
scanf("%d",&a[i][j]);
}
}
//dp过程
for(int i=r-1;i>=1;i--)//从倒数第二行开始
{
for(int j=1;j<=i;j++)//遍历这一行的元素
{
a[i][j]+=max(a[i+1][j],a[i+1][j+1]);//dp(观看图解理解该式子)
}
}
printf("%d",a[1][1]);
}
P1048 [NOIP2005 普及组] 采药
# [NOIP2005 普及组] 采药
## 题目描述
辰辰是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师。为此,他想拜附近最有威望的医师为师。医师为了判断他的资质,给他出了一个难题。医师把他带到一个到处都是草药的山洞里对他说:“孩子,这个山洞里有一些不同的草药,采每一株都需要一些时间,每一株也有它自身的价值。我会给你一段时间,在这段时间里,你可以采到一些草药。如果你是一个聪明的孩子,你应该可以让采到的草药的总价值最大。”
如果你是辰辰,你能完成这个任务吗?
## 输入格式
第一行有 $2$ 个整数 $T$($1 \le T \le 1000$)和 $M$($1 \le M \le 100$),用一个空格隔开,$T$ 代表总共能够用来采药的时间,$M$ 代表山洞里的草药的数目。
接下来的 $M$ 行每行包括两个在 $1$ 到 $100$ 之间(包括 $1$ 和 $100$)的整数,分别表示采摘某株草药的时间和这株草药的价值。
## 输出格式
输出在规定的时间内可以采到的草药的最大总价值。
## 样例 #1
### 样例输入 #1
```
70 3
71 100
69 1
1 2
```
### 样例输出 #1
```
3
```
## 提示
**【数据范围】**
- 对于 $30\%$ 的数据,$M \le 10$;
- 对于全部的数据,$M \le 100$。
**【题目来源】**
NOIP 2005 普及组第三题
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
struct node
{
int t,v;//时间//价值
}a[105];
int max_(int x,int y)
{
return x>y?x:y;
}
int main()
{
int T,M,dp[105][1005]={0};
scanf("%d%d",&T,&M);
for(int i=1;i<=M;i++)
{
scanf("%d%d",&a[i].t,&a[i].v);
}
for(int i=1;i<=M;i++)//种类的遍历
{
for(int j=1;j<=T;j++)//时间渐渐自增
{
if(j<a[i].t)//当时间不可以满足当前种类的时间的时候
{
dp[i][j]=dp[i-1][j];//赋值为上个
}
else
{
dp[i][j]=max_(dp[i-1][j],dp[i-1][j-a[i].t]+a[i].v);//取最大
}
}
}
printf("%d",dp[M][T]);
}
P1616 疯狂的采药
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
typedef long long ll;
ll max_(ll x,ll y)
{
return x>y?x:y;
}
struct node
{
ll t;
ll v;
}a[10005];//用于储存时间和价值
ll dp[10005*10005];//dp数组
int main()
{
int t,m,v,time;
scanf("%d%d",&t,&m);//时间和种类的输入
for(int i=1;i<=m;i++)
{ //时间和价值的录入
scanf("%d%d",&time,&v);
a[i].t=time;
a[i].v=v;
}
//dp过程
for(int i=1;i<=m;i++)//种类的遍历
{
for(int j=a[i].t;j<=t;j++)//从当前种类所需时间开始时间的渐增
{
dp[j]=max_(dp[j],dp[j-a[i].t]+a[i].v);
}
}
printf("%lld",dp[t]);
}