[BZOJ 2298] Problem A
Link:
Solution:
可以将每个人的话转化为$[l[i],r[i]]$的人得分相同
用$map$记录认为$[i,j]$相同的人数,$pos[i][j]$记录以$i$为右边界的左边界的可能取值
令$dp[i]$表示前$i$名中说真话的最多人数,
那么$dp[i]=max\{ dp[pos[i][j]-1]+min(i-pos[i][j]+1,mp[P(pos[i][j],i)])\}$
一定要记得取$min$,毕竟多出来的人也一定没说真话
Code:
#include <bits/stdc++.h> using namespace std; typedef pair<int,int> P; const int MAXN=1e5+10; int n,l,r,dp[MAXN]; map<P,int> mp; vector<int> pos[MAXN]; int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d%d",&l,&r); l=l+1;r=n-r; if(l<=r) { mp[P(l,r)]++;//可能有相同项 if(mp[P(l,r)]==1) pos[r].push_back(l); } } for(int i=1;i<=n;i++) { dp[i]=dp[i-1]; for(int j=0;j<pos[i].size();j++) dp[i]=max(dp[i],dp[pos[i][j]-1]+min(i-pos[i][j]+1,mp[P(pos[i][j],i)])); } printf("%d",n-dp[n]); return 0; }