poj 1695 Magazine Delivery(记忆化/dp)

来源:互联网 发布:期货交易程序化软件 编辑:程序博客网 时间:2024/05/29 07:03

Time Limit: 1000MS Memory Limit: 10000K   

Description

The TTT Taxi Service in Tehran is required to deliver some magazines to N locations in Tehran. The locations are labeled L1 to LN. TTT assigns 3 cars for this service. At time 0, all the 3 cars and magazines are located at L1. There are plenty of magazines available in L1 and the cars can take as many as they want. Copies of the magazine should be delivered to all locations, observing the following rules: 
  1. For all i = 2 .. N, magazines should be delivered at Li only after magazines are delivered at Li-1 . 
  2. At any time, only one of the three cars is driving, and the other two are resting in other locations.

The time to go from Li to Lj (or reverse) by any car is a positive integer denoted by D[i , j]. 
The goal is to organize the delivery schedule for the cars such that the time by which magazines are delivered to all N locations is minimum. 
Write a program to compute the minimum delivery time. 

Input

The input file contains M instances of this problem (1 <= M <= 10). The first line of the input file is M. The descriptions of the input data follows one after the other. Each instance starts with N in a single line (N <= 30). Each line i of the following N-1 lines contains D[i , j], for all i=1..N-1, and j=i+1..N.

Output

The output contains M lines, each corresponding the solution to one of the input data. In each line, the minimum time it takes to deliver the magazines to all N locations is written.

Sample Input

1510 20 3 45 10 208 1819

Sample Output

22



这道题题意是:给你三辆卡车,然后从1号点往n号点依次运货,题目给了从i点到j点的消耗,问如何才能使总消耗最小(必须上一个点的货送到了,才能送下一个点的)

很明显是一个记忆化dp的题,但是后看发现数据非常小,于是,于是用了一个四重循环,裸dp过了,只跑了16ms。。。。。。



#include <stdio.h>#include <string.h>#include <iostream>#include <math.h>#include <algorithm>#include <vector>#include <map>#define PI acos(-1.0)#define M 1000005  //10^6#define eps 1e-8#define LL long long#define moo 1000000007#define INF -999999999using namespace std;int a[40][40];int dp[40][40][40];   //三维数组,每一维代表一辆车,dp[i][j][k]表示第一辆车在i点,第二辆车在j点,第三辆车在k点时的总消耗int main(){    int T;    while(scanf("%d",&T)!=EOF)    {        while(T--)        {            int n;            memset(dp,0x3f,sizeof(dp));            scanf("%d",&n);            memset(a,0x3f,sizeof(a));            for(int i=1;i<n;i++)            {                for(int j=i+1;j<=n;j++)                    scanf("%d",&a[i][j]);            }            memset(dp,0x3f,sizeof(dp));            dp[1][1][1]=0;            for(int i=1;i<=n;i++)                for(int j=1;j<=n;j++)                    for(int k=1;k<=n;k++)                    {                        for(int t=1;t<=n;t++)                        {                            if(t<i&&j<i&&k<i&&(j==i-1||k==i-1||t==1))                                dp[i][j][k]=min(dp[i][j][k],dp[i-t][j][k]+a[i-t][i]);                            if(t<j&&i<j&&k<j&&(i==j-1||k==j-1||t==1))                                dp[i][j][k]=min(dp[i][j][k],dp[i][j-t][k]+a[j-t][j]);                            if(t<k&&i<k&&j<k&&(i==k-1||j==k-1||t==1))                                dp[i][j][k]=min(dp[i][j][k],dp[i][j][k-t]+a[k-t][k]);                        }                    }//if语句控制当某辆车到某点时,另外两辆都在该点前而且三辆里面至少有一辆上一步是停在前一点            int ans=1000000000;            for(int i=1;i<=n;i++)                for(int j=1;j<=n;j++)                {                    ans=min(ans,dp[i][j][n]);                    ans=min(ans,dp[i][n][j]);                    ans=min(ans,dp[n][i][j]);                }            cout<<ans<<endl;        }    }}


0 0
原创粉丝点击