Java 没有重复和顺序的动态编程/组合并不重要
假设我们有一条长度为L的铁路。我们需要在这条铁路的第一公里和最后一公里之间设置K个服务站。0公里和1公里的加油站已经免费建设。给定的是在这条铁路每公里修建一个服务站的价格,以及计算给定长度铁路服务价格的方程式 例如,我们有4公里长的铁路,并获得在铁路第n公里处修建一个车站的价格清单:Java 没有重复和顺序的动态编程/组合并不重要,java,algorithm,combinations,dynamic-programming,combinatorics,Java,Algorithm,Combinations,Dynamic Programming,Combinatorics,假设我们有一条长度为L的铁路。我们需要在这条铁路的第一公里和最后一公里之间设置K个服务站。0公里和1公里的加油站已经免费建设。给定的是在这条铁路每公里修建一个服务站的价格,以及计算给定长度铁路服务价格的方程式 例如,我们有4公里长的铁路,并获得在铁路第n公里处修建一个车站的价格清单: 5 22 13 我们还有站间服务的方程式-PRICE(len)=2*len*len+3*len。 因此,我们需要建立1站,我们可以在: 1st km-建造成本5,价格(1)=5(从0到1 km的服务)+价格(3)
5 22 13
我们还有站间服务的方程式-PRICE(len)=2*len*len+3*len。
因此,我们需要建立1站,我们可以在:
1st km-建造成本5,价格(1)=5(从0到1 km的服务)+价格(3)=27(从1到4 km的服务)=>37
2st公里-建筑成本22,价格(2)=14(从0到2公里的服务)+价格(2)=14(从2到4公里的服务)=>50
3st公里-建筑成本13,价格(3)=27(从0到3公里的服务)+价格(1)=5(从3到4公里的服务)=>69
最佳选择是在第一公里处修建1车站
如果我们需要建立两个电台怎么办
|S|_|_|_|F|
|S|1|2|_|F| 5+22+PRICE(1)+PRICE(1)+PRICE(2) = 5 + 22 + 5 + 5 + 14 = 51
|S|1|_|3|F| 5+13+PRICE(1)+PRICE(2)+PRICE(1) = 5 + 13 + 5 + 14 + 5 = 42
|S|_|2|3|F| 22+13+PRICE(2)+PRICE(1)+PRICE(1) = 22 + 13 + 14 + 5 + 5 = 59
所以,最好的办法是在第一公里和第三公里处设置两个车站
我的任务是找到给定长度的最低价格、要建造的车站数量、在特定公里和方程式上建造车站的价格
我的想法是计算len表以了解维持特定长度的成本。例如,它是表:
+------+------+------+------+
| idx0 | idx1 | idx2 | idx3 |
+------+------+------+------+
| 0 | 5 | 14 | 27 |
+------+------+------+------+
然后,我计算出在特定公里上建造任意两个车站的成本:
╔══════╦══════╦══════╦══════╦══════╗
║ ║ idx0 ║ idx1 ║ idx2 ║ idx3 ║
╠══════╬══════╬══════╬══════╬══════╣
║ idx0 ║ ║ ║ ║ ║
║ idx1 ║ ║ 5 ║ 32 ║ 32 ║
║ idx2 ║ ║ ║ 22 ║ 40 ║
║ idx3 ║ ║ ║ ║ 13 ║
╚══════╩══════╩══════╩══════╩══════╝
那么,我就创建递归,然后像这样进行:
public static void recur(int cost, int level, int idx) {
if (level == 0) {
if (min > cost + len[delka - idx]) {
min = cost + len[delka - idx];
System.out.println(min);
}
}
if (level > 0 && cost < min) {
for (int i = idx; i <= delka - level; i++) {
recur(cost + d[idx][i], level - 1, i);
}
}
publicstaticvoid重现(int-cost,int-level,int-idx){
如果(级别==0){
如果(最小值>成本+长度[delka-idx]){
最小值=成本+长度[delka-idx];
系统输出打印项次(最小值);
}
}
如果(级别>0&&成本 对于(int i=idx;i首先,请注意,对于任何位置x,如果我们已经计算了将最后一个站点放置在y km上的结果,y
示例代码如下:
int memo[MAX_KM][MAX_KM][MAX_STATION];
bool seen[MAX_KM][MAX_KM][MAX_STATION]; // if seen[km][pos_of_last_station][station_remaining] is true
// then this subproblem has already been solved. No need to solve it again
int dp(int KM, int pos_of_last_station, int station_remaining) {
if(KM == MAX_KM + 1) {
// reached the end
int len = (MAX_KM - pos_of_last_station);
return 2 * len * len + 3 * len;
}
if(seen[KM][pos_of_last_station][station_remaining]) {
// this sub problem has already been solved
return memo[KM][pos_of_last_station][station_remaining];
}
int ret = 2e9; // some large value
if(station_remaining > 0) {
// trying establishing a station on the current position
int len = KM - pos_of_last_station;
ret = min(ret, dp(KM + 1, KM, station_remaining - 1) + (2 * len * len + 3 * len) + cost[KM] ); // assuming cost[KM] is the cost to establish a station on KMth kilometer
}
ret = min(ret, dp(KM + 1, pos_of_last_station, station_remaining) );
seen[KM][pos_of_last_station][station_remaining] = true; // sub problem visited
memo[KM][pos_of_last_station][station_remaining] = ret; // storing the result for future utilization
return ret;
}
复杂性分析:将需要O(最大公里*最大公里*最大车站)时间和空间
警告:未测试代码