URAL 2072 Kirill the Gardener 3
阿新 • • 發佈:2018-01-28
div body con targe 表示 define spa ++ ret dp[i][1]=min(dp[i][1],dp[i-1][0]+abs(prel-nowl)+abs(nowl-nowr));
dp[i][1]=min(dp[i][1],dp[i-1][1]+abs(prer-nowl)+abs(nowl-nowr));
URAL 2072
思路:
dp+離散化
由於濕度的範圍很大,所以將濕度離散化
可以證明,先到一種濕度的最左端或者最右端,然後結束於最右端或最右端最優,因為如果結束於中間,肯定有重復走的路
狀態:dp[i][0]表示濕度為i結束於左端最優的步數
dp[i][1]表示濕度為i結束於右端最優的步數
初始狀態:dp[0][0]=dp[0][1]=0
狀態轉移:
dp[i][0]=min(dp[i][0],dp[i-1][0]+abs(prel-nowr)+abs(nowl-nowr));
dp[i][0]=min(dp[i][0],dp[i-1][1]+abs(prer-nowr)+abs(nowl-nowr));
dp[i][1]=min(dp[i][1],dp[i-1][1]+abs(prer-nowl)+abs(nowl-nowr));
prel和prer表示上一種濕度的最左端和最右端
nowl和nowr表示當前濕度的最左端和最右端
代碼:
#include<bits/stdc++.h> using namespace std; #define ll long long #define pb push_back #definemem(a,b) memset(a,b,sizeof(a)) const int N=1e5+5; const ll INF=0x3f3f3f3f3f3f3f3f; int a[N]; ll dp[N][2]; vector<int>pos[N]; vector<int>sz; int main(){ ios::sync_with_stdio(false); cin.tie(0); int n; cin>>n; for(int i=1;i<=n;i++)cin>>a[i],sz.pb(a[i]); sort(sz.begin(),sz.end()); sz.erase(unique(sz.begin(),sz.end()),sz.end());for(int i=1;i<=n;i++){ int t=lower_bound(sz.begin(),sz.end(),a[i])-sz.begin()+1; pos[t].pb(i); } mem(dp,INF); dp[0][0]=dp[0][1]=0; int prel=1,prer=1; for(int i=1;i<=sz.size();i++){ int nowl=pos[i][0],nowr=pos[i][pos[i].size()-1]; dp[i][0]=min(dp[i][0],dp[i-1][0]+abs(prel-nowr)+abs(nowl-nowr)); dp[i][0]=min(dp[i][0],dp[i-1][1]+abs(prer-nowr)+abs(nowl-nowr)); dp[i][1]=min(dp[i][1],dp[i-1][0]+abs(prel-nowl)+abs(nowl-nowr)); dp[i][1]=min(dp[i][1],dp[i-1][1]+abs(prer-nowl)+abs(nowl-nowr)); prel=nowl,prer=nowr; } cout<<min(dp[sz.size()][1],dp[sz.size()][0])+n<<endl; return 0; }
URAL 2072 Kirill the Gardener 3