Codeforces Round #821 (Div. 2) D E

E

首先发现无论何时,每个位置上至多只会有一个球。原因:每个时刻每个球都会移动,所以移动到某个点的时间一定,自然出生时间也一定,显然不可能会有 2 个点出生时间相同。

既然如此,假如 t 时刻某个位置有一个,那么显然它会在下个时刻到达 a 方向的点,那么下一个点到达这个位置的话,它会去与 a 相反的方向。这一步很厉害啊!要是分析到的话基本十拿九稳了。

那么既然如此,显然记录前缀时间在某个位置的球数前缀和之后 O(n2) 转移。

这一步的思考来源于直接记录某个时刻的肯定不行,考虑前缀时刻的相减性,以及前缀时间的可转移性。

#include <bits/stdc++.h> #define int long long #define pb push_back #define il inline using namespace std; const int N=123; int a[N][N],b[N][N],n=120; il int CEIL(int x) { if(x%2==0) return x/2; return x/2+1; } il int FLOOR(int x) { return x/2; } int sol(int t,int x,int y) { // cout<<"nex\n"; int qwq=x-1+y-1,s=t-qwq; if(s<0) { return 0; } // cout<<qwq<<" "<<s<<" "<<t<<" "<<x<<" "<<y<<'\n'; memset(a,0,sizeof(a)); a[1][1]=s+1; // for(int i=1;i<=x;i++) // for(int j=1;j<=y;j++) b[i][j]=0; // for(int nw=1;nw<=qwq;nw++) { // memset(b,0,sizeof(b)); for(int i=1;i<=x;i++) { for(int j=1;j<=y;j++) { a[i][j+1]+=(a[i][j]+1)/2; a[i+1][j]+=a[i][j]/2; // a[i][j]+=b[i][j]; } } // ++a[1][1]; // } return a[x][y]; } void solve() { int t,x,y; cin>>t>>x>>y; ++x; ++y; if(sol(t,x,y)!=sol(t-1,x,y)) cout<<"YES\n"; else cout<<"NO\n"; } signed main() { cin.tie(0); ios::sync_with_stdio(false); int T; cin>>T; while(T--) solve(); return 0; }

D

分析操作,典型套路确定每个位置操作奇偶性。

考虑显然最后有合法方案的当且仅当偶数个奇。

显然奇偶这个操作只会在为了 2 个奇使用相邻变换时使用。

偶偶显然废的。

所以仅考虑奇奇即可,即保留所有需要操作奇数的位置。我们发现假如相邻操作花费更少,这个的上界是确定的,我们一定可以通过 4 个分一组来实现全用这种操作。

否则的话,考虑一定当前剩余的是一段区间,不妨设挖空区间中间的 2 个,显然不会更优之类的。

#include <bits/stdc++.h> #define int long long #define pb push_back using namespace std; const int N=5002; bool a[N],b[N]; int n,cx,cy,vec[N],f[N][N],tot; inline int get(int x,int y) { bool fl=0; if(abs(x-y)==1) fl=1; x=vec[x]; y=vec[y]; if(x>y) swap(x,y); if(x+1==y) return min(cx,2*cy); int qwq=cy; if(fl) qwq=min(qwq,1ll*(y-x)*cx); return qwq; } int dfs(int l,int r) { if(~f[l][r]) return f[l][r]; if(l>r) return 0; int qwq=(int)(2e18); qwq=min(qwq,dfs(l+2,r)+get(l+1,l)); qwq=min(qwq,dfs(l+1,r-1)+get(r,l)); qwq=min(qwq,dfs(l,r-2)+get(r-1,r)); // cout<<l<<" "<<r<<" "<<qwq<<'\n'; return f[l][r]=qwq; } void sol() { cin>>n>>cx>>cy; for(int i=1;i<=n;i++) { char ch; cin>>ch; a[i]=ch-'0'; } for(int i=1;i<=n;i++) { char ch; cin>>ch; b[i]=ch-'0'; } tot=0; for(int i=1;i<=n;i++) { if(a[i]!=b[i]) { vec[++tot]=i; // cout<<i<<' '; } } if(tot&1) { cout<<"-1\n"; return ; } for(int i=0;i<=n;i++) for(int j=0;j<=n;j++) f[i][j]=-1; // cout<<get(1,4)<<' '<<get(2,3)<<" mmm "<<get(1,3)<<'\n'; if(cy<=cx&&tot>2) { cout<<(tot/2)*cy<<'\n'; return ; } cout<<dfs(1,tot)<<"\n"; } signed main() { cin.tie(0); ios::sync_with_stdio(false); int T; cin>>T; while(T--) sol(); return 0; }

__EOF__

本文作者F x o r G
本文链接https://www.cnblogs.com/xugangfan/p/16717366.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   FxorG  阅读(31)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示