已知:一輛汽車加滿油後可行使n千米,而旅途中有若干個加油站,試設計一個有效算法,指出應該在那個加油站停靠加油,使沿途加油次數最少,而後證實算法能產生最優解。java
用1,2,…,m表示旅途中的m個加油站,0表示出發地,用m+1表示目的地,s[0..m+1]表示加油站至出發地距離(s[0]<s[1]<s[2]<…<s[m]<s[m+1])。則很天然會想到使用貪心策略:每次跑不到下一個加油站了再加油。假設如今能夠跑n千米,則第一次加油位置爲s[i]<=n<s[i+1]時選擇在第i個加油站加油。則求第二次加油位置就變成了從s[i]出發的能夠跑n千米的車,則以後的s[i+1...m+1]=s[]-s[i],就是相同的子問題。算法
假設最優解爲a,b,c...
a<i時,a,b,c...爲最優解
a==i時,由於s[b]<=n+s[a],s[i]>s[a],因此s[b]<=n+s[a]<n+s[i],也是一個最優解
a>i時,由於n<s[i+1]<=s[a],不知足題意設計
第二次加油位置就變成了從s[i]出發的能夠跑n千米的車,則以後的s[i+1...m+1]=s[]-s[i],就是相同的子問題,以此類推直到沒有加油站只有目的地。code
/** * 計算通過加油站的次數 * @param s s(i)表示距離出發地的距離,最後一個表示目的地 * @param n 汽車能夠跑的千米數 */ public static void getNum(int[]s,int n) { int x=0;//已經跑過的路程 int num=0; for(int i=0;i<s.length-1;i++) { if(s[i]-x<=n&&s[i+1]-x>n) { x=s[i]; num++; System.out.println("在"+(i+1)+"處加油"); } } System.out.println("共加油"+num+"次"); } public static void main(String[] args) { //int[]s= {4,7,11,13};//4 3 4 2 int[]s= {4,6,9,10,14};//4 2 3 1 4 getNum(s,4); }
int[]s= {4,6,9,10,14};//4 2 3 1 4
int[]s= {4,7,11,13};//4 3 4 2
blog