A.
首先每个木板最多增加2个高度
设木板a,b,c,若a与b高度相同,那么我们让b高度+1,假设b现在又与c高度相同,那么我们让b的高度再+1
b只有两个相邻木板,所以b不用再改变了
所以当前木板可以有3个选择:不变,高度+1,高度+2
并要保证与前一块木板高度不同,那么我们枚举的时候把这个限制加上
ll a[N],b[N];
ll dp[N][3];
void solve() {
int n;cin>>n;
for(int i=0;i<=n;i++){
if(i==0){
dp[i][0]=dp[i][1]=dp[i][2]=inf;
continue;
}
cin>>a[i]>>b[i];
dp[i][0]=dp[i][1]=dp[i][2]=inf;
}
dp[0][0]=0;
for(int i=1;i<=n;i++){
for(int j=0;j<3;j++){
for(int k=0;k<3;k++){
if(a[i-1]+k!=a[i]+j){
dp[i][j]=min(dp[i][j],dp[i-1][k]+b[i]*j);
}
}
}
}
ll ans=inf;
for(int i=0;i<3;i++)ans=min(ans,dp[n][i]);
cout<<ans<<endl;
}
B.
奇偶性相同的数不能交换位置,也就是说奇偶性相同的数的相对位置不变,其他交换无限制
那么我们把奇数和偶数分别放在两个队列里,把较小的数放进答案里即可
queue<char>ji,ou;
void solve() {
while(ji.size())ji.pop();
while(ou.size())ou.pop();
string s;cin>>s;
for(int i=0;i<s.size();i++){
if((s[i]-'0')&1)ji.push(s[i]);
else ou.push(s[i]);
}
while(ji.size()&&ou.size()){
if(ji.front()<ou.front()){
cout<<ji.front();ji.pop();
}else if(ji.front()>ou.front()){
cout<<ou.front();ou.pop();
}
}
while(ji.size()){
cout<<ji.front();ji.pop();
}
while(ou.size()){
cout<<ou.front();ou.pop();
}
cout<<endl;
}
C.
因为点都在街道上,且街道贯穿整个图
若一个点是十字路口,那么任一点到这点都可以是曼哈顿距离
任一点在水平街道上,那么十字路口的垂直街道一定通过这条水平街道;在垂直街道上同理
若一点在水平街道上,一点在垂直街道上,那么它们也可以是曼哈顿距离,理由同上
现在考虑两点都在水平(垂直)街道上
在同一条水平(垂直)街道上一定是曼哈顿距离
考虑不在同一条街道上的
如这张图上的3、4两点,若有一条水平街道在3的高度-4的高度之间,那么它们就可以是曼哈顿距离,没有,则不是
但判两点,过于暴力
去找有贡献的点的共性(找区间,找范围)
转化:
如图的第3个点,比y坐标大的第一条水平线记为l,那么高度处于y坐标与l之间的且同为竖直线上的这些点都与第3点形成贡献
代码有注释:
vector<int>vx,vy;
void solve() {
int n,m,k;cin>>n>>m>>k;
for(int i=1,x;i<=n;i++){
cin>>x;
vx.push_back(x);//垂直线
}
for(int i=1,x;i<=m;i++){
cin>>x;
vy.push_back(x);//水平线
}
map<int,int>mpx,mpy;
map<pair<int,int>,int>mp_xy,mp_yx;
ll ans=0;
while(k--){
int x,y;cin>>x>>y;
int px= lower_bound(vx.begin(),vx.end(),x)-vx.begin();//在哪一条垂直线上
int py= lower_bound(vy.begin(),vy.end(),y)-vy.begin();//在哪一条水平线上
if(vx[px]==x&&vy[py]==y)continue;//若该点水平线垂直线都有,也就是十字路口,那么它与任意一点都可以是曼哈顿距离,对答案无贡献,跳过
if(vx[px]==x){//有垂直线,那么必定无水平线,找到的是比y坐标大的第一条水平线,记为l,mpy[]代表所有无水平线的并且处于y坐标与l之间的点的数量,这些点对答案都有贡献
ans=ans+mpy[py]-mp_xy[{px,py}];//mp_xy[]表示无水平线且下标为px的垂直线的集合
mpy[py]++;mp_xy[{px,py}]++;//更新
}
else{//同理
ans=ans+mpx[px]-mp_yx[{py,px}];
mpx[px]++;mp_yx[{py,px}]++;
}
}
cout<<ans<<endl;
vx.clear();vy.clear();
}
标签:21,int,px,py,iwtgm,水平线,街道,mp
From: https://www.cnblogs.com/wwww-/p/17828134.html