“科大讯飞杯”第十七届同济大学程序设计预选赛暨高校网络友谊赛 C 张老师的旅行 区间无决策DP

经过简单的分析可知:

张老师一定是从起点开始,往左走,往右走,再往左走。最终走完n个点。

也就是说,走过的地点始终是连续的。自然想到区间dp。

dp[i][j][2]      走完区间l,r最终停在左/右端点的最少用时 (且满足区间内所有点的ti限制)

转移比较显然,注意必须满足ti限制才进行转移。

 

#include 
using namespace std;
typedef long long ll;
#define ls (o<<1)
#define rs (o<<1|1)
#define pb push_back
const double PI= acos(-1.0);
const int M = 1e3+7;
/*
int head[M],cnt;
void init(){cnt=0,memset(head,0,sizeof(head));}
struct EDGE{int to,nxt,val;}ee[M*2];
void add(int x,int y){ee[++cnt].nxt=head[x],ee[cnt].to=y,head[x]=cnt;}
*/
ll dp[M][M][2];//走完区间l,r的最少用时 ,最终停在左/右端点的最少用时 
int p[M],t[M];
int main()
{
	ios::sync_with_stdio(false);
  	cin.tie(0);
  	int n;
  	cin>>n;
	memset(dp,60,sizeof(dp));
  	for(int i=1;i<=n;i++)cin>>p[i];
  	for(int i=1;i<=n;i++)
  	{
  		cin>>t[i];
  		if(t[i]==0)dp[i][i][0]=dp[i][i][1]=0;
	}
 
  	for(int len=2;len<=n;len++)
  	{
  		for(int l=1;l+len-1<=n;l++)
  		{
  			int r=l+len-1;
  			ll tp=min(dp[l+1][r][0]+p[l+1]-p[l],dp[l+1][r][1]+p[r]-p[l]);
  			if(tp<=t[l])dp[l][r][0]=tp;
  			tp=min(dp[l][r-1][0]+p[r]-p[l],dp[l][r-1][1]+p[r]-p[r-1]);
  			if(tp<=t[r])dp[l][r][1]=tp;
  		}
	}
	ll mi=min(dp[1][n][1],dp[1][n][0]);
	if(mi>=1e8)mi=-1;
	cout<

 

你可能感兴趣的:(动态规划——区间dp)