POJ 3661:Running 区间DP

Running

题目链接:

http://poj.org/problem?id=3661

题意:

有一只牛在跑步,在第 i 分钟它可以跑Ni米,疲惫值加1(疲惫值初始为0),或者休息一分钟,疲惫值减1(只有疲惫值到了0才能重新开始跑步),当匹配值达到M时它必须休息,且第N分钟结束时牛的疲惫值必须为0,求这只牛最远可以跑几米。

题解:

设dp[i][j]在 i 分钟里疲惫值限制为j的情况下牛可以跑的最远距离。一般情况下这样设就行了,但是因为题目限制只要开始休息就必须休息到疲惫值为0,所以这里将dp再加一重变成dp[i][j][0]和dp[i][j][1],分别代表在第 i 分钟能量为 j 时是休息还是继续跑步

很明显dp[i][j][0]是dp[i-1][j+1][0]和dp[i-1][j+1][1]间的较大值,注意当j==0的时候dp[i][j][0]还可以由dp[i-1][j][0]得到(即上一分钟能量已经为0,但是这一分钟还是休息)

而dp[i][j][1]=dp[i-1][j-1][1]+a[i](上一分钟跑步,这一分钟还在跑步),同样,这里也要注意一点,当j==1时dp[i][j][1]还可以由dp[i-1][j+1][1]+a[i]得到(上一分钟休息且疲惫值归0了)

代码

#include<stdio.h>
#include<string.h>
const int N=10001;
const int M=501;
int dp[N][M][2];
int mmax(int x,int y)
{
	return x>y?x:y;
}
void solve()
{
	int n,m,x;
	memset(dp,0,sizeof(dp));
	while(~scanf("%d%d",&n,&m))
	{
		for(int i=1;i<=n;++i)
		{
			scanf("%d",&x);
			for(int j=0;j<=m;++j)
			{
				if(j!=0)
				{
					dp[i][j][1]=dp[i-1][j-1][1]+x;
					if(j==1)dp[i][j][1]=mmax(dp[i][j][1],dp[i-1][j-1][0]+x);
				}
				if(j!=m)
				{
					dp[i][j][0]=mmax(dp[i-1][j+1][0],dp[i-1][j+1][1]);
					if(j==0)dp[i][j][0]=mmax(dp[i][j][0],dp[i-1][j][0]);
				}
			}
		}
		printf("%d\n",dp[n][0][0]);
	}
}
int main()
{
	solve();
	return 0;
}
 
时间: 2024-11-08 11:21:14

POJ 3661:Running 区间DP的相关文章

POJ 1179 Polygon 区间DP

链接:http://poj.org/problem?id=1179 题意:给出一个多边形,多边形的每个顶点是一个数字,每条边是一个运算符号"+"或者"x".要求的过程如下,手下移除一条边,即这条边不做运算.之后每次移除一条边,将其两边的数字进行对应边的运算,用得到的数字来替代原来的两个点.要求所有边都移除以后得到的最大的答案. 思路:典型的区间DP,在过程中每次操作的处理方式为dp_max[i][j]=dp[i][k]*dp[k+1][j],dp_max[i][j]

poj 3661 Running dp

题意: 有n分钟时间,每分钟牛能跑d[i]路程,在每分钟,牛可以选择跑,这样疲劳度会+1,也可以选择不跑,这样疲劳度会-1(最少到0),问n分钟后疲劳度为0时最多能跑多远,注意牛要疲劳度为0才能继续跑. 分析: 设dp[i][j]表示i分钟结束奶牛疲劳度为j时能跑的最远距离,则转移有:dp[i-1][j-1]->dp[i][j]+d[i],dp[i][j]->dp[i+j][0]; 代码: //poj 3661 //sep9 #include <iostream> using na

POJ 2955 Brackets (区间DP)

题意:给定一个序列,问你最多有多少个合法的括号. 析:区间DP,dp[i][j] 表示在 第 i 到 第 j 区间内最多有多少个合法的括号. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include <cstdlib> #include <cmath> #include <ios

POJ 1160 (区间DP+四边形优化)

这个转移方程不好想,尤其是一段值的解是中间,不明觉厉.dp[i][j] 用i个邮局,覆盖前j个村庄的最小值. 还有就是区间dp的平行四边形优化,这个题的转移方程并不是"区间DP",所以枚举状态要逆着(很花时间),且用一个邮局覆盖都是从0断开了相当于没有断开. 类比于石子归并,矩阵链乘等标准区间DP,其所需状态之前就已经获得,不用倒推 #include <cstdio> #include <cstring> #include <iostream> us

POJ 2955-Brackets(区间DP)

Brackets Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3340   Accepted: 1716 Description We give the following inductive definition of a "regular brackets" sequence: the empty sequence is a regular brackets sequence, if s is a reg

POJ 1159 Palindrome(区间DP/最长公共子序列+滚动数组)

Palindrome Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 56150   Accepted: 19398 Description A palindrome is a symmetrical string, that is, a string read identically from left to right as well as from right to left. You are to write a

poj 3661 Running(区间dp)

Description The cows are trying to become better athletes, so Bessie is running on a track for exactly N (1 ≤ N ≤ 10,000) minutes. During each minute, she can choose to either run or rest for the whole minute. The ultimate distance Bessie runs, thoug

[dp] poj 3661 Running

题意: 一只奶牛可以跑n分钟,疲劳度上限是m. 接下来是每分钟可以跑a[i]米. 然后对于每分钟可以选择跑或者休息,跑的话疲劳度增加一点疲劳度. 休息的话每分钟减少一点疲劳,但是如果选择休息,那么必须休息至疲劳度为零. 问n分钟后,疲劳度为0的,所能跑的最远距离. 思路: 水dp,dp[i][j]代表前i分钟疲劳度为j跑的最远距离. 状态转移就是跑或者休息. 代码: #include"cstdlib" #include"cstdio" #include"c

POJ 2955 Brackets (区间dp 括号匹配)

Brackets Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3951   Accepted: 2078 Description We give the following inductive definition of a "regular brackets" sequence: the empty sequence is a regular brackets sequence, if s is a reg