hrbust 1331 ACM之路 邂逅DP【dp】


ACM之路 邂逅DP


Time Limit: 1000 MS


Memory Limit: 65536 K


Total Submit: 158(51 users)


Total Accepted: 67(46 users)


Rating:


Special Judge: No


Description


MM迷上了ACM,不可救药。。。

算法绝非一天两天就能学好,需要不断的看书学习,不断的敲代码,不断的看书学习,不断的敲代码。。。

这是一条没有尽头的路。。。

尼玛的搞ACM的伤不起啊!!!

详情见:搞ACM的你伤不起?http://heliang.me/blog/?p=548

最近又搞上了动态规划,这动态规划伤不起啊!

《算法导论》的第一个个动态规划就老长一篇了,MM看得头大,就跑过去问GG了。

GG看着MM粉红可爱的脸蛋,瞬间激情燃烧,充满活力,想着:我不会动态规划也得会了。

下面是《算法导论》上的第一个动态规划问题。

装配线问题

Colonel汽车公司在有两条装配线的工厂内生产汽车,一个汽车底盘在进入每一条装配线后,在每个装配站会在汽车底盘上安装不同的部件,最后完成的汽车从装配线的末端离开。如下图1所示。(竟然粘贴不上来,题目地址:http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=1331)

装配线示意图

每一条装配线上有n个装配站,编号为j=1,2,...,n,将装配线i(i为1或2)的第j个装配站表示为S(i,j)。

装配线1的第j个站S(1,j)和装配线2的第j个站S(2,j)执行相同的功能。

然而这些装配站是在不同的时间建造的,并且采用了不同的技术,因此,每个站上完成装配所需要的时间也不相同,即使是在两条装配线上相同位置的装配站也是这样。

把每个装配站上所需要的装配时间记为a(i,j),并且,底盘进入装配线i需要的时间为e(i),离开装配线i需要的时间是x(i)。

正常情况下,底盘从一条装配线的上一个站移到下一个站所花费的时间可以忽略,但是偶尔也会将未完成的底盘从一条装配线的一个站移到另一条装配线的下一站,比如遇到紧急订单的时候。

假设将已经通过装配站S(i,j)的底盘从装配线i移走到另一条装配线所花费的时间为t(i,j),现在的问题是要确定在装配线1内选择哪些站以及在装配线2内选择哪些站,以使汽车通过工厂的总时间最小。

GG思考了一会,然后耐心的给MM解答了。。。


Input


有多组测试数据,对于每组测试数据,第1行为一个整数n(0<n<=100000),表示有n个装配站,第2行和第3行是装配线1和2的入站时间、站1到站n的装配时间,出站时间,每行n+2个整数(<=1000000)。第4行和第5行是装配线1和2移动到另外一条装配线的下一个站的时间,每行有n-1个整数(<=100)。


Output


对于每组测试数据输出一行,包含一个整数,需要的最少装配时间。


Sample Input


6

2 7 9 3 4 8 4 3

4 8 5 6 4 5 7 2

2 3 1 3 4

2 1 2 2 1


Sample Output


38


Source


2012 Spring Contest 5 - Binary Search, Greedy, DP


Author


《算法导论》

题目连接:http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=1331

思路:题目大意说的很清楚,这里直接分析解题方法。

首先设dp【2】【i】,dp【1】【i】表示第一行上边连接到i这个位子用的最小消耗,dp【2】【i】则表示第四行上边连接到i这个位子的最小消耗。根据题中给出的图,发现除了起点和第一个点以及最后一个点之外,都有两种来到这个点的方法。一个是从左边过来,一个是从左下过来,辣么不难推出状态转移方程:

dp【1】【i】=min(dp【1】【i-1】,dp【2】【i-1】+a【3】【i-1】过来消耗的那个值)+a【1】【i】(当前节点值);

dp【2】【i】=min(dp【2】【i-1】,dp【1】【i-1】+a【2】【i-1】过来消耗的那个值)+a【1】【i】(当前节点值);

对于i==2的时候,和i==n+2的时候,dp【1/2】【i】=dp【1/2】【i-1】+a【1/4】【i】;

注意的点:数据值比较大,需要用long long int

思路构建完毕,上代码.

AC代码:

#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
#define ll long long int
ll a[5][100005];
ll dp[3][100005];
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        memset(dp,0,sizeof(dp));
        memset(a,0,sizeof(a));
        for(int j=1; j<=n+2; j++)
        {
            scanf("%lld",&a[1][j]);
        }
        for(int j=1; j<=n+2; j++)
        {
            scanf("%lld",&a[4][j]);
        }
        for(int j=2; j<=n; j++)
        {
            scanf("%lld",&a[2][j]);
        }
        for(int j=2; j<=n; j++)
        {
            scanf("%lld",&a[3][j]);
        }
        for(int i=1;i<=n+2;i++)
        {
            if(i==1)
            {
                dp[1][i]=a[1][i];
                dp[2][i]=a[4][i];
                continue;
            }
            if(i==2||i==n+2)
            {
                dp[1][i]=dp[1][i-1]+a[1][i];
                dp[2][i]=dp[2][i-1]+a[4][i];
                continue;
            }
            dp[1][i]=min(dp[1][i-1],dp[2][i-1]+a[3][i-1])+a[1][i];
            dp[2][i]=min(dp[2][i-1],dp[1][i-1]+a[2][i-1])+a[4][i];
        }
        printf("%lld\n",min(dp[1][n+2],dp[2][n+2]));
    }
}
时间: 2024-10-14 09:51:48

hrbust 1331 ACM之路 邂逅DP【dp】的相关文章

[ACM] hdu 3555 Bomb (数位DP,统计1-N中含有“49”的总数)

Bomb Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others) Total Submission(s): 7187 Accepted Submission(s): 2512 Problem Description The counter-terrorists found a time bomb in the dust. But this time the terrorists impro

[ACM] POJ 3071 Football (概率DP)

Football Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2875   Accepted: 1462 Description Consider a single-elimination football tournament involving 2n teams, denoted 1, 2, -, 2n. In each round of the tournament, all teams still in the

POJ 2288 Islands and Bridges 哈密尔顿路 状态压缩DP

找最长的其实是很裸的状态压缩DP,棘手的地方是要统计数量,其实只要再来一个数组存就好. 不过代码比较长,细节要注意的地方毕较多,wa了很多发,还是要仔细啊 用递推和记忆化搜索分别写了一遍 #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #include <

[ACM] ZOJ 3725 Painting Storages (DP计数+组合)

Painting Storages Time Limit: 2 Seconds      Memory Limit: 65536 KB There is a straight highway with N storages alongside it labeled by 1,2,3,...,N. Bob asks you to paint all storages with two colors: red and blue. Each storage will be painted with e

OUC&amp;&amp;我的ACM之路(三)

OUC && 我的ACM之路(三) 时间匆匆,转眼间,省赛我都已经参加过三届了.前面两篇日志:OUC && 我的ACM之路(一)  OUC && 我的ACM之路(二)首先吐槽一下这次省赛题目实在太简单了,也许HIT认为我们就这个水平吧.SD加油,早日冲出final.  rank在这里 其实我也没啥好总结的,只是感概,时间过得匆匆,很多话,前面两篇里面已经说了.最后说一下,实际比赛的时候,ABG三个数学题目,ouc_abc写的,Orz,要当时的状态,我应该是推

ACM之路(16)—— 数位DP

题目就是kuangbin的数位DP. 先讲C题,不要62,差不多就是一个模板题.要注意的是按位来的话,光一个pos是不够的,还需要一维来记录当前位置是什么数字,这样才能防止同一个pos不同数字的dp值混在一起.直接丢代码: 1 #include <stdio.h> 2 #include <algorithm> 3 #include <string.h> 4 #include <iostream> 5 #include <vector> 6 #in

acm山东省赛 Games(dp取数)

Games Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Problem Description Alice and Bob are playing a stone game. There are nn piles of stones. In each turn, a player can remove some stones from a pile (the number must be positive and no

HDU 2196 Computer (树上最长路)【树形DP】

<题目链接> 题目大意: 输出树上每个点到其它点的最大距离. 解题分析: 下面的做法是将树看成有向图的做法,计算最长路需要考虑几种情况. dp[i][0] : 表示以i为根的子树中的结点与i的最大距离 dp[i][1] : 表示以i为根的子树中的结点与u的次大距离 dp[i][2] : 表示i往父亲节点方向走的最大距离 第一就是点 i 在以点 i 为根的子树中的最长距离,这个可以直接在点 i 的子树中求得: 第二就是点 i 朝父亲节点方向的最长距离,这个距离分为三种: 1) 点 i 在以 fa

HDU ACM 4597 Play Game -&gt;区间DP+记忆化搜索

分析:两个人都足够聪明,因此每个阶段都拿最大的.dp[sa][ea][sb][eb]分别表示区间1的开始为sa,结束为ea,区间2的开始为sb,结束为eb时能拿到的最大值.之后分别从四个方向上拿,是个搜索的过程. [cpp] view plaincopyprint? #include<iostream> using namespace std; int dp[25][25][25][25];  //dp[sa][ea][sb][eb],分别表示区间1的开始,结束,区间2的开始,结束 int a