poj 1695 Magazine Delivery(记忆化/dp)

这道ACM题目要求使用三辆卡车从1号点到N号点依次运送杂志,确保每个点的杂志在前一个点送达后才能运送。每辆车每次只能运输一处,其余两车休息。输入和输出信息描述了运输过程的细节。解决方案采用记忆化动态规划,尽管数据规模较小,但通过四重循环的裸DP方法也能在16ms内快速求得最小总消耗。
摘要由CSDN通过智能技术生成

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

1
5
10 20 3 4
5 10 20
8 18
19

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 -999999999
using 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;
        }
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值