【Algothrim】动态规划法实例2

来源:互联网 发布:js ui隐藏不安全 编辑:程序博客网 时间:2024/05/16 06:56

例题:

Switches are mounted in a row on a long worktable.
When you give numbers for the switches from 1 to 1000000 at interval of 1 centimeter from the left, they are always on integers.
All of the switches turn on and turn off one by one by the time appointed.
At the end, all of them must turn off.
A robot does this job and it has a position a certain number accurately between the numbers.


By the way, the power consumption of the switch is 1W per 1 second.
Depending on the time to turn off all of the switches, the power consumption varies.
An operator, Mr. Lee does not want to waste the power because he has strong saving spirit.


When a position of the switch, let’s help Mr. Lee in calculating the minimum power consumption until all of the switches turn off.
The robot moves a constant speed of 1cm/sec and the robot’s moving time is not counted.


Time limit : 1 sec (Java : 2 sec)


[Input]
There can be more than one test case in the input file. The first line has T, the number of test cases.
Then the totally T test cases are provided in the following lines (T ≤ 10 )


In each test case,
In the first line, The number of switches (N) and the switch number (S) where the robot is stopped at the first time are given. (1 ≤ N ≤ 1000 & 1 ≤ S ≤ 1000000)
The locations of the switches are given from the next line to the line of the number (N) from the third row.
The locations of the switches are over 1 and below 1000000.


[Output]
In the each line, generate the minimum power consumption until all switches turn off.


[I/O Example]

Input
2
2 5
3
7
4 10
1
9
11
19


Output
8
44


分析:

http://zhidao.baidu.com/link?url=crK09aYmAxcyaoW4YIngQI2ThJR173Jw2htoSzSleWhL_rXwT9RX4O7CI-e7HKAKBVKlbLypCX7xC6tYbHNOAa

百度这个链接和这道题目是一样的,就是动态规划题目。同样的需要推导出动态规划公式。

首先我们先选取区间(x1,x2), 表示这个区间内的灯已经被关闭。

现在让机器人向左/右移动,即被覆盖区间变成 (x1,x2)/ (x1,x2+1).直到覆盖给定区间的两头。就求出了所需的值。

 那么我们可以得到公式如下: 

dp(x1,x2) = { min(dp(x1-1,x2)  + x1向左侧移动到x1-1所消耗的,  dp(x1,x2+1) + x2向右侧移动到x2+1所消耗的}

这里,我们用cost [I][j][k]来保存这个值。

k表示方向,左移就是1,右移就是0, 

min(cost[x1][x2][0], cost[x1][x2][1]).


实现代码(Implement by chunyin)

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <string.h>

#define MAX 1005

using namespace std;

long data[MAX], S, N;
long Answer, cost[MAX][MAX][2];

long switchOff(int left, int post, int right, int isLeft){
 if(cost[left][right][isLeft] != -1)//如果已经有值,表示已经计算出结果,返回
  return cost[left][right][isLeft];

 long lCost, rCost;
 lCost=0; rCost=0;

 if(left > 0){
  lCost=switchOff(left-1,left,right,0) + (N-(right-left-1))*(data[post]-data[left]);  //从left左移一部到left-1位置所需消耗
 }
 if(right < N+1){
  rCost=switchOff(left,right,right+1,1) + (N-(right-left-1))*(data[right]-data[post]); //从right像右移一步到right+1位置所需消耗
 }

 if(lCost == 0){
  cost[left][right][isLeft]=rCost;
 }else if(rCost == 0){
  cost[left][right][isLeft]=lCost;
 }else {
  if(lCost < rCost){
   cost[left][right][isLeft]=lCost;
  }else {
   cost[left][right][isLeft]=rCost;
  }
 }

 return cost[left][right][isLeft];
}

int main(int argc, char** argv)
{
 int tc, T, i;
 
 //freopen("input.txt", "r", stdin);

 cin >> T;
 for(tc = 0; tc < T; tc++)
 {
  cin >> N >> S;
  for(i=1;i<=N;i++) {
   cin >> data[i];
  }
  
  Answer = 0;
  
  data[++N]=S;
  sort(data+1, data+N+1);


  memset(cost, -1, sizeof(cost));
  //tim vi tri bat dau
  for(i=1;i<=N;i++){
   if(data[i] == S)
    break;
  }

  Answer=switchOff(i-1,i,i+1,0);
  // Print the answer to standard output(screen).
  cout << Answer << endl;

 }

 return 0;//Your program should return 0 on normal termination.
}



0 0
原创粉丝点击