题解 P7985 [USACO21DEC] Paired Up P
题目难度:USACO P+/NOI-
子任务 1:
设
时间复杂度:
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define pii pair<int,int>
#define vi vector<int>
int main(){
T=read(),n=read(),K=read();
vector <pii> cow[2];
cow[0].pb({0,0}),cow[1].pb({0,0});
rep(i,1,n){
cin>>c;
int x=read(),y=read();
cow[c=='H'].pb({x,y});
sum+=y;
}
A=sz(cow[0]),B=sz(cow[1]);
if(T==1){
vector <vi> dp(A+1,vi(B+1));
rep(i,1,A)rep(j,1,B){
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
if(abs(cow[0][i].x-cow[1][j].x)<=K)
dp[i][j]=max(dp[i][j],dp[i-1][j-1]+cow[0][i].y+cow[1][j].y);
}
printf("%d\n",sum-dp[A][B]);
}
}
子任务 2:
对于最大化未匹配的权值和,我们考虑使用类似的 dp 状态。但是注意到在上述转移时,有时候我们考虑的并不是最大匹配,只是因为最优解只产生于最大匹配(若不是最大匹配,多匹配两头牛显然更优),我们才能得到
于是我们需要把最大匹配这一限制加入我们的 dp 状态,具体地,我们加入一维
- 牛
k 的品种是H - 牛
k 与当前牛的距离大于K
状态量是
时间复杂度:
vector <vector<vi>> dp(A+1,vector<vi>(B+1,vi(n+1,-1)));
dp[0][0][n]=0;
rep(i,0,A)rep(j,0,B)rep(k,0,n){
if(dp[i][j][k]==-1)continue;
if(i<A&&j<B&&abs(cow[0][i].x-cow[1][j].x)<=K)
Max(dp[i+1][j+1][k],dp[i][j][k]);
if(i<A&&(!(A<=k&&k<n&&cow[0][i].x<=cow[1][k-A].x+K)))
Max(dp[i+1][j][i],dp[i][j][k]+cow[0][i].y);
if(j<B&&(!(k<A&&cow[1][j].x<=cow[0][k].x+K)))
Max(dp[i][j+1][A+j],dp[i][j][k]+cow[1][j].y);
}
int ans = 0;
rep(i,0,n)Max(ans,dp[A][B][i]);
printf("%d\n",ans);
子任务 1:
考虑最终的优化,
当然我们也可以转换钦定的品种:如果之前我们被强制不选 H 牛,那么最后一个未匹配的 H 牛最多是第
时间复杂度:
per(i,A,1)per(j,B,1){
if(chk(i,j))lst[i][j]=lst[i+1][j+1]+1;
else lst[i][j]=0;
}
int j=1;
rep(i,1,A){
while(j<=B&&(chk(i,j)||G[j].x<H[i].x))j++;
nxtH[i] = j;
}
j=1;
rep(i,1,B){
while(j<=A&&(chk(j,i)||H[j].x<G[i].x))j++;
nxtG[i] = j;
}
memset(f,-0x3f,sizeof(f));
memset(g,-0x3f,sizeof(g));
nxtG[0] = nxtH[0] = 1;
f[0][0] = g[0][0] = 0;
rep(i,0,A)rep(j,0,B){
int cnt = max(nxtH[i]-j-1,0);
if(i+cnt<=A && lst[i+1][j+1]>=cnt)
Max(g[i+cnt][j+cnt],f[i][j]);
cnt = max(nxtG[j]-i-1,0);
if(j+cnt<=B && lst[i+1][j+1]>=cnt)
Max(f[i+cnt][j+cnt],g[i][j]);
if(i<A && j<B && chk(i+1,j+1)){
Max(f[i+1][j+1],f[i][j]);
Max(g[i+1][j+1],g[i][j]);
}
if(i<A) Max(f[i+1][j],f[i][j]+H[i+1].y);
if(j<B) Max(g[i][j+1],g[i][j]+G[j+1].y);
}
printf("%d\n",max(f[A][B],g[A][B]));