动态规划 就是:给定一个问题,我们把它拆成一个个子问题,直到子问可以直接解决。然后把子问题的答案保存起来,以减少重量计算,再根据子问题答察反推,得出问解的一种方法。
题目:
这天,一只蜗牛来到了二维坐标系的原点。
在 x 轴上长有 n 根竹竿。它们平行于 y 轴,底部纵坐标为 0,横坐标分别为 x1, x2, ..., xn。竹竿的高度均为无限高,宽度可忽略。蜗牛想要从原点走到第 n 个竹竿的底部也就是坐标 (xn, 0)。它只能在 x 轴上或者竹竿上爬行,在 x 轴上爬行速度为 1 单位每秒;由于受到引力影响,蜗牛在竹竿上向上和向下爬行的速度分别为 0.7 单位每秒和 1.3 单位每秒。
为了快速到达目的地,它施展了魔法,在第 i 和 i + 1 根竹竿之间建立了传送门(0 < i < n),如果蜗牛位于第 i 根竹竿的高度为 ai 的位置 (xi , ai),就可以瞬间到达第 i + 1 根竹竿的高度为 bi+1 的位置 (xi+1, bi+1),请计算蜗牛最少需要多少秒才能到达目的地。
输出格式:
输入共 1 + n 行,第一行为一个正整数 n;
第二行为 n 个正整数 x1, x2, . . . , xn;
后面 n − 1 行,每行两个正整数 ai , bi+1。
样例输入:
3 1 10 11 1 1 2 1
样例输出:
4.20
DP三步走
1.确定dp元素
2.明确状态,得到状态转移方程
3.数据初始化
package test;import java.io.*;public class Main {public static StreamTokenizer st=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));public static void main(String[] args) throws IOException{int n=nextInt();int[] x=new int[n];int[] a=new int[n];int[] b=new int[n];double[] footMin=new double[n];double[] doorMin=new double[n];for(int i=0;i<n;i++){x[i]=nextInt();}for(int i=0;i<n-1;i++){a[i]=nextInt();b[i]=nextInt();}footMin[0]=x[0]*1.0;doorMin[0]=x[0]*1.0+a[0]*1.0/0.7;int d;for(int i=1;i<n;i++) {d=x[i]-x[i-1];if(b[i-1]>a[i]) {doorMin[i]=Math.min(doorMin[i-1]+(b[i-1]-a[i])*1.0/1.3,footMin[i-1]+d+a[i]*1.0/0.7);}else {doorMin[i]=Math.min(doorMin[i-1]+(a[i]-b[i-1])*1.0/0.7,footMin[i-1]+d+a[i]*1.0/0.7);}footMin[i]=Math.min(doorMin[i-1]+b[i-1]*1.0/1.3,footMin[i-1]+d*1.0);}System.out.println(String.format("%.2f",footMin[n-1]));
}private static int nextInt() throws IOException{// TODO 自动生成的方法存根st.nextToken();return (int)st.nval;}}