思路
不会载球跨过原点,数轴两边分开考虑。按距离排序。
可以设 表示 型已经取掉了前 个, 型取掉了前 个。两个相交的同类型匹配不优,可以规定必须转移目前最远端的位置。
只能把两种型号放在一起考虑,设 表示已经取了前 个的最小代价。。
还有一种转移是,设 是 型, 要和之前最近的 型 匹配。此时, 中全为 ,若存在 和 匹配,那可以改为 和 更优。所以 都和 之前的 型匹配。令 为最近的 中两种类型数量相等的位置,在这个区间中可以有后面 匹配前面 的转移,代价为区间中所有 的下标和。
code
int n,c,ans;
int dp[maxn],sum[2][maxn];
int sovle(vector<pii> a){
int n=a.size();
a.pb({0,0});sort(a.begin(),a.end());
unordered_map<int,int> mp;mp[0]=0;
for(int i=1;i<=n;i++)sum[0][i]=sum[0][i-1],sum[1][i]=sum[1][i-1],sum[a[i].se][i]+=a[i].fi;
for(int i=1,s=0;i<=n;i++){
dp[i]=dp[i-1]+2*a[i].fi;
if(i>=2)dp[i]=min(dp[i],dp[i-2]+2*a[i].fi+(a[i-1].se==a[i].se)*c);
s+=a[i].se*2-1;
if(mp.find(s)!=mp.end()){
int j=mp[s];
dp[i]=min(dp[i],dp[j]+2*(sum[a[i].se][i]-sum[a[i].se][j]));
}
mp[s]=i;
}
return dp[n];
}
void work(){
n=read();c=read();
vector<pii> a,b;
for(int i=1;i<=n;i++){
int x=read(),c=read();
if(x>0)a.pb({x,c});
else b.pb({-x,c});
}
ans=sovle(a)+sovle(b);
printf("%lld\n",ans);
}