0906比赛总结
省流:只会写暴力
T1
考虑你后面遇到障碍再复制和在最开始就复制好足够数量的是一样的。
然后走到某一个窗口所需要的高度就是窗口高度+之前的所有的障碍的高度。
对于所有相同高度的,我们处理出来它的数量,然后直接向上枚举,计算当前选了这个高度以下的窗户的总花费,然后取max就好。
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,m,c,p;
const int N=1e6+100;
int t[N],h[N],cnt[N];
int read() {int x;cin>>x;return x;}
signed main() {
freopen("drone.in","r",stdin);
freopen("drone.out","w",stdout);
n=read();m=read();c=read();p=read();
int maxx=0;
int sum=0;
vector<int>o;
for(int i=1;i<=n+m;i++) {
t[i]=read();h[i]=read();
if(t[i]==1) sum=sum+h[i];
else {
h[i]+=sum;
o.push_back(h[i]);
}
// maxx=max(maxx,h[i]);
// o.push_back(h[i]);
}
int ans=0;
o.push_back(0);
sort(o.begin(),o.end());
o.erase(unique(o.begin(),o.end()),o.end());
for(int i=1;i<=n+m;i++) {
if(t[i]==1) continue;
h[i]=lower_bound(o.begin(),o.end(),h[i])-o.begin();
cnt[h[i]]++;
}
sum=0;
int mm=o.size();
for(int i=1;i<mm;i++) {
// cerr<<sum<<" "<<o[i]<<endl;
ans=max(ans,(sum+cnt[i])*p-(o[i]-1)*c);
// if((sum+cnt[i])*p-(o[i]-1)*c==10) cerr<<cnt[i]<<" "<<o[i]<<endl;
sum=sum+cnt[i];
}
cout<<ans<<endl;
return 0;
}
T2
赛时对着这题想了很久的dp都不会,然后就直接放弃了,跑去写了个dfs,拿了40pts跑路了,然后dfs写完之后看了看T3和T4,又开始对着这题想dp,但是到最后都没想到怎么优化。
先考虑暴力dp,我们设 \(dp_i\) 表示生产了 \(i\) g反物质所需要的最小的代价,然后对于所有的我们取个max,每次转移都是暴力枚举如果当前用 \(j\) 实验所能转移到 \(dp_i\) 的方案。
\[dp_i=max_{j=1}^n(min_{k=l_j}^{r_j}dp_{i-k}-c_j+10^9\times k)
\]
针对上式进行化简,同时令 \(g_i=dp_i-10^9\times i\),于是我们发现,\(dp_i\) 是对前面一个区间取min,然后我们考虑用st表优化这个,但是st表也要跟着更新,所以我们每次枚举完就去重新更新当前i为末尾的所有st表,于是就做完了。
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,a;
const int N=2e6+100,M=1e9;
int l[N],r[N],c[N],dp[N],st[N][30],lg[N];
int read() {int x;cin>>x;return x;}
int ask(int l, int r){
int step = lg[r - l + 1];
return min(st[l][step], st[r - (1ll << step) + 1][step]);
}
signed main() {
freopen("antimatter.in","r",stdin);
freopen("antimatter.out","w",stdout);
// ios::sync_with_stdio(false);
// cin.tie(0);cout.tie(0);
n=read();a=read();
// int minnr=0x3f3f3f3f3f3f3f3f;
for(int i=2;i<=a;i++) {
lg[i]=lg[i/2]+1;
}
for(int i=1;i<=n;i++) {
l[i]=read();r[i]=read();c[i]=read();
}
for(int i=1;i<=a;i++) {
for(int j=1;j<=n;j++) {
if(r[j]>i) continue;
int minn=ask(i - r[j], i - l[j]);
dp[i]=max(dp[i],minn+i*M-c[j]);
}
st[i][0]=dp[i]-i*M;
for(int j = 1; (i - (1ll << j)) + 1 >= 0; j++){
st[i - (1ll << j) + 1][j] = min(st[i - (1ll << j) + 1][j - 1], st[i - (1ll << j) + (1ll << (j - 1)) + 1][j - 1]);
}
}
int maxx=0;
for(int i=a;i>=0;i--) {
maxx=max(maxx,dp[i]);
}
cout<<maxx<<endl;
return 0;
}
T3
可以使用拓扑排序,我们发现,对于0-1-1的这种边,我们要求 0 在 1 变为 1 之后要变成 1 一次,然后再变回去,也就是说,0 一定在 1 之后变。0-0-1 的边也是同理,然后都建完边了之后直接拓扑排序,就可以判断了。
**#include<bits/stdc++.h>
using namespace std;
int n,m;
const int N=2e5+100;
int u[N],v[N],w[N],d[N],ru[N];
vector<int>e[N];
int read() {int x;cin>>x;return x;}
void work() {
n=read();m=read();
// int u,v,w;
for(int i=1;i<=m;i++) {
u[i]=read();v[i]=read();w[i]=read();
}
for(int i=1;i<=n;i++) {
d[i]=read();
ru[i]=0;
e[i].clear();
}
for(int i=1;i<=m;i++) {
if(d[u[i]]==d[v[i]]) {
if(d[u[i]]!=w[i]) {
cout<<"NO\n";
return;
}
}
}
for(int i=1;i<=m;i++) {
if(d[u[i]]==d[v[i]]) continue;
if(d[u[i]]) swap(u[i],v[i]);
if(w[i]==1) {
e[v[i]].push_back(u[i]);ru[u[i]]++;
}
else {e[u[i]].push_back(v[i]);ru[v[i]]++;}
}
queue<int>q;
for(int i=1;i<=n;i++) {
if(ru[i]==0) {
q.push(i);
}
}
while(q.size()) {
int x=q.front();q.pop();
for(auto y:e[x]) {
ru[y]--;
if(ru[y]==0) q.push(y);
}
}
for(int i=1;i<=n;i++) {
if(ru[i]) {
cout<<"NO"<<endl;
return ;
}
e[i].clear();
}
for(int i=1;i<=m;i++) {
if(d[u[i]]==d[v[i]]) continue;
if(d[u[i]]) swap(u[i],v[i]);
if(w[i]==1) {
e[v[i]].push_back(u[i]);ru[u[i]]++;
}
else {e[u[i]].push_back(v[i]);ru[v[i]]++;}
}
int ans=0;
for(int i=1;i<=n;i++) {
if(d[i]) ans++;
else ans+=2;
if(ru[i]==0) q.push(i);
}
cout<<"YES"<<"\n"<<ans<<endl;
while(q.size()) {
int x=q.front();
q.pop();
if(d[x]) cout<<x<<" 1\n";
else {
cout<<x<<" 1\n"<<x<<" 0\n";
}
for(auto y:e[x]) {
ru[y]--;
if(ru[y]==0) {
q.push(y);
}
}
}
}
signed main() {
freopen("interactive.in","r",stdin);
freopen("interactive.out","w",stdout);
int t=read();
while(t--) {
work();
}
return 0;
}
T4
还没订题,赛时主要都在看T2,对于T4只在最后10min打了个暴力就跑路了,根本就没认真看。