题意翻译
在一条直线上有n件珠宝,已知每件珠宝的位置,并且第 i 件珠宝在 ti 时刻就消失,问能否将所有的珠宝收集起来?如果能,求出最短时间。搜集能瞬间完成。
dp[i][j][k] 表示把i到j的珠宝全收完的最优解,k==0表示在i点,k==1表示在j点
#include<bits/stdc++.h> #define inf 0x3f3f3f3f using namespace std; const int maxn = 1e4+10; int kase = 0; struct node { int pos,tim; }treasure[maxn]; int n,f[maxn][maxn][2],vis[maxn][maxn][2]; bool cmp(const node& a,const node& b) { return a.pos<b.pos; } int dp(int x,int y,int z) { if(x==y) return 0; int& ans=f[x][y][z]; if(vis[x][y][z]==kase) return ans; vis[x][y][z]=kase; ans=inf; if(z==0) ans=min(min(ans,dp(x+1,y,1)+treasure[y].pos-treasure[x].pos),dp(x+1,y,0)+treasure[x+1].pos-treasure[x].pos); else ans=min(min(ans,dp(x,y-1,1)+treasure[y].pos-treasure[y-1].pos),dp(x,y-1,0)+treasure[y].pos-treasure[x].pos); if(ans>=treasure[z==0?x:y].tim) ans=inf; return ans; } int main() { //freopen("in.txt","r",stdin); while(scanf("%d",&n)!=EOF) { ++kase; for(int i=1;i<=n;i++) scanf("%d%d",&treasure[i].pos,&treasure[i].tim); //for(int i=1;i<=n;i++) f[i][i][0]=f[i][i][1]=0; //sort(treasure+1,treasure+1+n,cmp); int ans=min(dp(1,n,1),dp(1,n,0)); if(ans==0x3f3f3f3f) printf("No solution "); else printf("%d ",ans); } }