码迷,mamicode.com
首页 > 其他好文 > 详细

UVA1632 Alibaba

时间:2016-08-14 07:42:33      阅读:186      评论:0      收藏:0      [点我收藏+]

标签:

题解:

刚开始想的时候状态转移想不到。

模模糊糊想到的是对于当前点,访问的下一个点要么是右边最近的未访问点,要么是左边的未访问点。然后就不知道了。

后来看了题解。dp[i][j][0]表示访问完[i,j]且最终在i点,1则是在j点

那么不难想到状态转移方程

dp[i][j][1]=min(dp[i][j-1][1]+val1,dp[i][j-1][0]+val2);

dp[i][j][0]=min(dp[i+1][j][1]+val3,dp[i+][j][0]+val4);

但是这样空间不够。。

就开个滚动数组。。根据区间的增长进行滚动即可.

对于滚动数组,,先写出非滚动数组。。然后在思考如何滚动即可

代码:

#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
#define se second
#define fs first
#define ll long long
#define CLR(x) memset(x,0,sizeof x)
#define MC(x,y) memcpy(x,y,sizeof(x))  
#define SZ(x) ((int)(x).size())
#define FOR(it,c) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();it++)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1 
#define INF 1e18
typedef pair<int,int> P;
const double eps=1e-9;
const int maxn=10010;
const int mod=10007;
    
ll read()
{
    ll x=0,f=1;char ch=getchar();
    while(ch<0||ch>9){if(ch==-)f=-1;ch=getchar();}
    while(ch>=0&&ch<=9){x=x*10+ch-0;ch=getchar();}
    return x*f;
}
//-----------------------------------------------------------------------------

/*
    没开滚动。。判断写得有点挫。。。 
    for(int k=1;k<=n-1;k++)
    {
        for(int i=1;i<=n-k;i++)
        {
            if(dp[i+1][i+k-1][0]+a[i+1]-a[i]>=b[i]) val1=INF;
            else val1=a[i+1]-a[i];
            if(dp[i+1][i+k-1][1]+a[i+k]-a[i]>=b[i]) val2=INF;
            else val2=a[i+k]-a[i];
            if(dp[i][i+k-1][1]+a[i+k]-a[i+k-1]>=b[i+k]) val3=INF;
            else val3=a[i+k]-a[i+k-1];
            if(dp[i][i+k-1][0]+a[i+k]-a[i]>=b[i+k]) val4=INF;
            else val4=a[i+k]-a[i];
            dp[i][i+k][0]=min(dp[i+1][i+k][0]+val1,dp[i+1][i+k][1]+val2);
            dp[i][i+k][1]=min(dp[i][i+k-1][1]+val3,dp[i][i+k-1][0]+val4);
            if(dp[i][i+k][0]>INF) dp[i][i+k][0]=INF;
            if(dp[i][i+k][1]>INF) dp[i][i+k][1]=INF;
        }
    }
    if(dp[1][n][0]>=INF&&dp[1][n][1]>=INF) printf("No solution\n");
    else printf("%lld\n",min(dp[1][n][0],dp[1][n][1]));

*/
//ll dp[maxn][maxn][2];
ll a[maxn],b[maxn];
ll dp[maxn][2][2];

int main()
{
    int n;
    ll val1,val2,val3,val4;
    while(~scanf("%d",&n))
    {
      CLR(dp);
      for(int i=1;i<=n;i++) scanf("%lld%lld",&a[i],&b[i]);
      int now=0,pre=1;
      for(int k=1;k<=n-1;k++)
      {
         now^=1,pre^=1;
         for(int i=1;i<=n-k;i++)
         {
            dp[i][now][0]=min(dp[i+1][pre][0]+a[i+1]-a[i],dp[i+1][pre][1]+a[i+k]-a[i]);
            dp[i][now][1]=min(dp[i][pre][1]+a[i+k]-a[i+k-1],dp[i][pre][0]+a[i+k]-a[i]);
            if(dp[i][now][0]>=b[i]) dp[i][now][0]=INF;
            if(dp[i][now][1]>=b[i+k]) dp[i][now][1]=INF;                        
         }
     }
      ll ans=min(dp[1][now][0],dp[1][now][1]);
      if(ans>=INF) printf("No solution\n");
      else printf("%lld\n",ans);
    }  
    return 0;
}

 

UVA1632 Alibaba

标签:

原文地址:http://www.cnblogs.com/byene/p/5769383.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!