标签:
题解:
刚开始想的时候状态转移想不到。
模模糊糊想到的是对于当前点,访问的下一个点要么是右边最近的未访问点,要么是左边的未访问点。然后就不知道了。
后来看了题解。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; }
标签:
原文地址:http://www.cnblogs.com/byene/p/5769383.html