DP:从零开始的动态规划 Description Input Output Sample Input 1 Sample Output 1
从现在开始学习dp
来一个入门的
T1:数字三角形
时间限制: 1000 ms 内存限制: 65536 KB【题目描述】
观察下面的数字金字塔。写一个程序查找从最高点到底部任意处结束的路径,使路径经过数字的和最大。每一步可以从当前点走到左下方的点也可以到达右下方的点。
在上面的样例中,从13到8到26到15到24的路径产生了最大的和86。
【输入】
第一个行包含R(1≤ R≤1000),表示行的数目。
后面每行为这个数字金字塔特定行包含的整数。
所有的被供应的整数是非负的且不大于100。
【输出】
单独的一行,包含那个可能得到的最大的和。
【输入样例】
5 13 11 8 12 7 26 6 14 15 8 12 7 13 24 11
【输出样例】
86
#include<bits/stdc++.h> #define re register #define ll long long using namespace std; template <typename T> inline void read(T &x) { int f=1;x=0;char c=getchar(); for(;c>'9'||c<'0';c=getchar()) if(c=='-') f=-1; for(;c>='0'&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48); x*=f; } int n; int a[1011][1011]; int f[1011][1011]; int main() { read(n); for(re int i=1;i<=n;i++) for(re int j=1;j<=i;j++) read(a[i][j]); for(re int i=n;i>=1;i--) for(re int j=1;j<=i;j++) f[i][j]=max(f[i+1][j],f[i+1][j+1])+a[i][j]; cout<<f[1][1]; return 0; }
T2:公路乘车 tyvj1015
【描述 Description】
一个特别的单行街道在每公里处有一个汽车站。顾客根据他们乘坐汽车的公里使来付费。例如样例的第一行就是一个费用的单子。
没有一辆车子行驶超过10公里,一个顾客打算行驶n公里(1<=n<=100),它可以通过无限次的换车来完成旅程。最后要求费用最少。
没有一辆车子行驶超过10公里,一个顾客打算行驶n公里(1<=n<=100),它可以通过无限次的换车来完成旅程。最后要求费用最少。
【输入格式 InputFormat】
第一行十个整数分别表示行走1到10公里的费用(<=500)。注意这些数并无实际的经济意义,即行驶10公里费用可能比行驶一公里少。
第二行一个整数n表示,旅客的总路程数。
第二行一个整数n表示,旅客的总路程数。
【输出格式 OutputFormat】
仅一个整数表示最少费用。
【样例输入 SampleInput】
12 21 31 40 49 58 69 79 90 101
15
【样例输出 SampleOutput】
147#include<bits/stdc++.h> #define re register #define ll long long using namespace std; template <typename T> inline void read(T &x) { int f=1;x=0;char c=getchar(); for(;c>'9'||c<'0';c=getchar()) if(c=='-') f=-1; for(;c>='0'&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48); x*=f; } const int INF=10101011; int a[101]; int f[10101]; int main() { for(re int i=1;i<=10;i++) read(a[i]); int tot,ans=0; read(tot); for(re int i=1;i<=tot;i++) f[i]=INF; f[1]=a[1]; for(re int i=2;i<=tot;i++) for(re int j=1;j<=10;j++) if(i>=j) { f[i]=min(f[i],f[i-j]+a[j]) ; } cout<<f[tot]; return 0; }
T3:抢金块
地面上有一些格子,每个格子上面都有金块,但不同格子上的金块有不同的价值,你一次可以跳S至T步(2≤S<T≤10)。例如S=2,T=4,你就可以跳2步、3步或4步。你从第一个格子起跳,必须跳到最后一个格子上,请你输出最多可以获得的金块的总价值。如果不能到达n,则输出0.
Input
第一行是格子个数n(n<1000);第二行是S和T,保证T大于S(2≤S<T≤10);
第三行是每个格子上的金块价值Pi(0<Pi<10000)。
Output
输出最多可以获得的金块的总价值。
Sample Input 1
10
2 3
4 5 8 2 8 3 6 7 2 9
Sample Output 1
36
#include<bits/stdc++.h> #define re register #define ll long long using namespace std; template <typename T> inline void read(T &x) { int f=1;x=0;char c=getchar(); for(;c>'9'||c<'0';c=getchar()) if(c=='-') f=-1; for(;c>='0'&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48); x*=f; } int a[10101]; int f[10101]; int main() { int n,s,t; read(n); memset(f,0,sizeof(f)); read(s),read(t); for(re int i=1;i<=n;i++) read(a[i]); f[1]=a[1]; for(re int i=2;i<=n;i++) for(re int j=s;j<=t;j++) if(i-j>0&&f[i-j]!=0) f[i]=max(f[i],f[i-j]+a[i]); cout<<f[n]; return 0; }