目录
Codeforces Round 982 (Div. 2)
A
思路
因为图形可以重叠, 所以答案就是最长的长和最长的宽组成的矩形周长.
code
void func(void)
{
int n;
cin >> n;
int l = 0,r = 0;
while(n--)
{
int x,y;
cin >> x >> y;
l = max(l,x), r = max(r,y);
}
cout << 2*l+2*r << '\n';
}
B
思路
因为 $n \le 2000 $, 所以可以用 \(O(n^2)\), 那么暴力求每个点后续有几个数大于自己, 然后求删去前面所有数和后续大于自己数的代价, 最后遍历最小值即可.
code
void func(void)
{
int n,mx = 0;
cin >> n;
vector<int> a(n),cnt(n);
for(auto &i : a) cin >> i;
for(int i=0;i<n;++i)
{
for(int j=i+1;j<n;++j)
{
if(a[j] > a[i]) cnt[i] ++;
}
}
int ans = M;
for(int i=0;i<n;++i)
{
ans = min(ans,i+cnt[i]);
}
cout << ans << '\n';
}
C
思路
设数组实际长度为 \(len\), 对于每个数字, 在 \(len+1-i\) 时可以被使用, 而\(1-i\) 固定
, 那么就可以处理出每个数字在什么长度时可以被使用, 且同效果(长度)数只能被使用一次
那么每个数只会从能变为此效果的数转移而来,
\(dp[b[i]+i-1] = dp[b[i]]+i-1\), \(b[i]+i-1\) 代表新的可获得长度, \(b[i]\)为转移前长度.
卡题原因
dp
不熟练
code
void func(void)
{
int n,ans = 0;
cin >> n;
int len = n;
vector<int> a(n+1),b(n+1),c;
map<int,bool> cvis;
map<int,int> dp;
map<int,vector<int>> mp;
for(int i=1;i<=n;++i) cin >> a[i];
for(int i=1;i<=n;++i)
{
b[i] = a[i] - (len-i+1);
if(b[i] == 0)
{
c.push_back(i);
}
if(b[i] >= 0) mp[b[i]].push_back(i);
}
dp[0] = n;
cvis[0] = true;
for(auto &temp : mp)
{
if(cvis.count(temp.x) == 0) continue;
for(auto &i : temp.y)
{
cvis[b[i]+i-1] = true;
dp[b[i]+i-1] = max(dp[b[i]+i-1],dp[temp.x]+i-1);
}
}
for(auto &i : dp) ans = max(ans,i.y);
cout << ans << '\n';
}
D
思路
完全背包.
未ac原因
先是没看到 \(1 \le n \cdot m \le 3 \cdot 10^5\),
后是把 \(b\) 单调减遗忘了.
补题还二分总写不出来, 实际甚至可以不二分.
code
void func(void)
{
int n,m,ans = 0,mx = 0;
cin >> n >> m;
vector<int> a(n+1),s(n+1),b(m+1);
vector<vector<int>> dp(m+1,vector<int>(n+1,M));
for(int i=1;i<=n;++i)
{
cin >> a[i];
mx = max(a[i],mx);
s[i] = s[i-1] + a[i];
}
for(int i=1;i<=m;++i)
{
cin >> b[i];
}
if(mx > b[1])
{
cout << -1 << '\n';
return ;
}
dp[0][0] = 0;
for(int i=1;i<=m;++i)
{
for(int j=0;j<=n;++j)
{
dp[i][j] = dp[i-1][j];
if(j == 0) continue;
int k=0;
int be = 0,ed = j;
while(be != ed-1)
{
int mid = (be+ed) >> 1;
if(s[j]-b[i] <= s[mid]) ed = mid;
else be = mid;
}
dp[i][j] = min(dp[i][j],dp[i][(s[j]-b[i] <= s[be] ? be : ed)]+m-i);
}
}
cout << dp[m][n] << '\n';
}
标签:code,982,题解,void,cin,int,vector,Div,dp
From: https://www.cnblogs.com/zerocloud01/p/18510235