# tioj 1090 Grazing on the Run https://tioj.ck.tp.edu.tw/problems/1090 很像joi本選某一題,很久以前看過但當時不會,然後現在也忘了哪一題了qq * 簡單來說就是設定他的左右界以及他停在哪裡,所以可以定一個dp狀態為: * dp[i][j][0/1] = 吃掉i到j之間的蘋果(假設蘋果已排序),並且停留在左邊或右邊(分別是0/1) 轉移: ```cpp= int left=n-(j-i); dp[i][j][0]=min(dp[i+1][j][0]+abs(pt[i]-pt[i+1])*left, dp[i+1][j][1]+abs(pt[i]-pt[j])*left); dp[i][j][1]=min(dp[i][j-1][0]+abs(pt[j]-pt[i])*left, dp[i][j-1][1]+abs(pt[j]-pt[j-1])*left); // left為剩下多少蘋果沒被吃掉 // abs(pt[x]-pt[y])要乘以left因為對之後的left個蘋果都會貢獻abs(pt[x]-pt[y])的不新鮮度,所以先把他算起來 ``` * 記得dp[i][i][0/1]的base case ```cpp= #include <bits/stdc++.h> #define pb push_back #define f first #define s second #define rep(X, a,b) for(int X=a;X<b;++X) #define ALL(a) (a).begin(), (a).end() #define SZ(a) (int)(a).size() #define NL "\n" using namespace std; typedef pair<long long,long long> pll; typedef pair<int,int> pii; typedef long long ll; ll dp[1010][1010][2]={0}; int main(){ ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); int n, l; cin>>n>>l; vector<ll> pt(n+1, 0); rep(i,1,n+1) cin>>pt[i]; sort(ALL(pt)); for(int i=1;i<=n;++i) dp[i][i][0]=dp[i][i][1]=abs(pt[i]-l)*n; for(int k=2;k<=n;++k){ for(int i=1;i+k-1<=n;++i){ int j=i+k-1; int left=n-(j-i); dp[i][j][0]=min(dp[i+1][j][0]+abs(pt[i]-pt[i+1])*left, dp[i+1][j][1]+abs(pt[i]-pt[j])*left); dp[i][j][1]=min(dp[i][j-1][0]+abs(pt[j]-pt[i])*left, dp[i][j-1][1]+abs(pt[j]-pt[j-1])*left); // cout<<i<<" "<<j<<" "<<dp[i][j][0]<<" "<<dp[i][j][1]<<NL; } } cout<<min(dp[1][n][0], dp[1][n][1])<<NL; } ```