UVA 1632-Alibaba(DP)

题目大意:在一条直线上有n(n<=10000)个点有宝藏,每个点的坐标都是整数,每个宝藏在某个时间到之后都会消失,可以在任何一个点出发,移动一个单位需要一个单位的时间,问最少需要多少时间拿完所有宝藏,如果不能拿完所有的输出No solution。输入按照坐标递增顺序。

a[i]表示第i个宝藏的位置,b[i]表示消失的时间。

首先注意到对于任意区间(i,j),拿完所有宝藏之后必然在i或j两者之一。所以用d[i][j][0]表示拿完第i个到第j个之间的所有宝藏,且最后位于i,用d[i][j][1]表示拿完第i个到第j个之间的所有宝藏且最后位于j。

程序用滚动数组优化内存消耗,递推是按照区间的宽度递增的顺序,所以也是按照这样滚动的。

状态转移方程:

d[i][j][0]=min { d[i+1][j][0]+a[i+1]-a[i],d[i+1][j][1]+a[i+j]-a[i]}

d[i][j][1]=min { d[i][j-1][0]+a[i+j]-a[i],d[i][j-1][1]+a[i+j]-a[i+j-1]}

在程序中还需要判断递推过程中是否能在消失前到达,不能到达则置为INF。

#include<stdio.h>
#include<stdlib.h>
int a[10010];
int b[10010];
int d[2][10010][2];
int main(void)
{
	int i,j,n,cur,min;
	while(scanf("%d",&n)==1)
	{
		for(i=1;i<=n;i++)
		{
			scanf("%d%d",&a[i],&b[i]);
		}
		cur=0;
		for(j=1;j<=n;j++)
		{
			d[0][j][0]=d[0][j][1]=(b[j]>0)?0:(1<<30);
		}
		for(i=1;i<n;i++)
		{
			cur^=1;
			for(j=1;j<=n-i;j++)
			{
				d[cur][j][0]=d[cur^1][j+1][0]+a[j+1]-a[j]>d[cur^1][j+1][1]+a[j+i]-a[j]?d[cur^1][j+1][1]+a[j+i]-a[j]:d[cur^1][j+1][0]+a[j+1]-a[j];
				d[cur][j][1]=d[cur^1][j][0]+a[j+i]-a[j]>d[cur^1][j][1]+a[j+i]-a[j+i-1]?d[cur^1][j][1]+a[j+i]-a[j+i-1]:d[cur^1][j][0]+a[j+i]-a[j];
				d[cur][j][0]=d[cur][j][0]<b[j]?d[cur][j][0]:(1<<30);
				d[cur][j][1]=d[cur][j][1]<b[j+i]?d[cur][j][1]:(1<<30);
			}
		}
		min=d[cur][1][0]>d[cur][1][1]?d[cur][1][1]:d[cur][1][0];
		if(min==(1<<30))
		{
			printf("No solution\n");
		}
		else
		{
			printf("%d\n",min);
		}
	}
	return 0;
}
时间: 2024-08-04 10:40:54

UVA 1632-Alibaba(DP)的相关文章

UVA 1371 - Period(DP)

6.4 一些说明 数据属性可以重写同名的方法属性.这是为了避免在大型系统中产生问题的意外名称冲突.所以用一些减少冲突的常用方法是很有效果的.常用的方法包括:大写字母方法名称,用唯一的字符串来做为数据属性的名称(可以是个下划线_)或者用动词命名方法和用名字命名数据属性. 数据属性就像和对象的普通用户一样可以被方法引用.换句话说,类不能用来实现纯净的数据类型.事实上,在python中不能强制数据隐藏,一切基于约定.(另一方面,如C中写的,python的实现可以做到完全隐藏实现细节并且在必要是可以控制

uva 10271 Chopsticks (DP)

uva 10271 ChopsticksA 题目大意:给出客人数K和筷子数量N(支),总人数M=客人数K + 8(还有家人).要找出M组筷子,每组包括3支筷子,每组都有一个badness值,badness值为每组中较小的两支筷子的差值.求怎样分组,才能使总差值最小. 解题思路:dp[i][j]表示使用第i支筷子,并已组成j组是的最小badness总值.在取筷子时,要注意在所有未被使用的筷子中,要有比选取的两根筷子更长的筷子. #include <cstdio> #include <cst

【UVa】Jump(dp)

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4198 约瑟夫变形 根据f(n)=(f(n-1)+m)%n 因为是求倒数第几个 那么我们只要求出f(倒数第几个)的值然后再带进去即可. (没理解的自行面壁..) 而f(倒数第几个)=(m-1)%倒数第几个 然后就行了.. #include <cstdio> #include <

Uva 10465-Homer Simpson(DP)

题目链接:点击打开链接 DAG上的最长路. 题意:相当于给两种硬币的面值,每种可以用无限次,问恰好组成S 最多能用多少个硬币.如果不能恰好组成S,输出最大能组成的面值x(x<S)所需的最大硬币数 和 S-x. #include <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include <string> #include <cctype&

UVA 10163-Storage Keepers(DP)

题目大意:有N(1<=N<=100)个仓库需要看管,有M(1<=M<=30)名应聘者,每个人有能力属性Pi(1<=Pi<=1000).所有仓库都是一样的,每个仓库只能被一人看守,一人可看守多个仓库,当一人看守u个仓库时,每个仓库的安全度为Uj=Pi/u,总安全度为min Uj.雇佣一个能力值为Pi的人需要花费Pi元.求最大的总安全度,和在这样的情况下的最小花费. 先dp一次,求出可能的最大总安全度max,再次dp,求出在安全度为max下的最小花费. 第一次dp:用d[i

UVA 1366-Martian Minging(DP)

题目大意:有一个n(1<=n<=500)行m(1<=m<=500)列的网格,每个网格有两种矿,yeyenum和bloggium,在网格的西边是yeyenum的精炼厂,北边是bloggium的精炼厂,每个网格有一定数量的两种矿,现在要安排一个传送带系统,传送带只能由南向北或者由东向西,传送带同方向的可以连续传,只有传到相应精炼厂才是有效的,问许多能拿到多少矿. 用d[i][j]表示到第i行第j列时,前i行j列能产生的最大的矿数量,用a[i][j]表示在第i行从第1列加到第j列的yey

UVA 473-Raucous Rockers(DP)

题目大意:有n首歌,m个光盘,每个光盘最多能放t时间的歌,给出每首歌的长度,必须按顺序录入光盘(可以选择不录某几首歌),最多能录多少首歌. 用d[i][j][0]表示前i首歌,放j首,最少用多少个光盘,用d[i][j][1]表示前i首歌,放j首,在光盘最少的前提下,最后一个光盘可以剩余的最多容量.根据是否放第i首歌完成递推. 这样递推是正确的,因为前i首歌,放j首的情况下,最佳的情况就是尽量少的用光盘,并且使得最后一个光盘容量尽量大(例如如果用的光盘数多一些,并且最后一个光盘的容量更大一些,这样

【UVa】Salesmen(dp)

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4170 d[i,j]前i个字符j结尾 d[i,j]=min{d[i-1,k], j和k有边}+(a[i]!=j) 初始化d[1,j]=1, d[1,a[1]]=0 #include <cstdio> #include <cstring> #include <cma

Uva 562-Dividing coins(DP)

题目链接:点击打开链接 题意:n个硬币,给出每个硬币的价值,要求把这些硬币分成两组,使得两组的价值差尽量小. 可以发现如果可以平分,那么价值差肯定为0,那么依次从sum/2 --> 0 枚举i,如果用上述硬币的价值组合可以组成i 那么sum-i-i就是答案.如何判断是否对于一个数i用这些硬币可以凑出来,用背包判就可以了,注意是01背包. #include <algorithm> #include <iostream> #include <cstring> #inc

UVA 11081 Strings(DP)

Given 3 strings of only lowercase letter you have to count the number of ways you can construct the third string by combining two subsequences from the first two strings. After deleting 0 or more characters from a string we can get its subsequence. F