QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#760946 | #3040. Container | yz_ly | WA | 0ms | 9352kb | C++14 | 2.9kb | 2024-11-18 20:19:30 | 2024-11-18 20:19:31 |
Judging History
answer
#include<bits/stdc++.h>
using namespace std;
inline int read(){
int f=1,x=0;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
f=-f;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
return f*x;
}
inline void write(int k){
if(k<0){
putchar('-');
k=-k;
}
if(k>9)
write(k/10);
putchar(k%10+'0');
}
/*
归位所有B
考虑操作,只有翻转BR,BRR,BBR有用,分别是移动一格,移动两格,移动两格并且越过一个蓝色弹珠
移动两次一格不比移动一次两格优
那么如果要移动一个B动d格,贡献就是d/2*(C+4)+d%2*(C+3)+delta,delta表示需要越过的B的个数
那么最后的答案和移动的奇偶性是有关系的,而且发现最后在奇数位置的数对应原来的的位置也肯定是顺序排列的,偶数位置同理
定义dp[i][j]表示前i个奇数位置和前j个偶数位置的B已经匹配好了,这样的最小代价是多少
容易发现匹配的最后一个肯定是i+j,也容易发现最优方案下一定不存在BRB这种组合
O(n^3)要除以各种常数,是能够通过的
构造方案保证向左移动的最左边先动,向右移动最右边先动就可以了
*/
int n,C,a[1005],b[1005],c[1005],num,num1,num2,dp[1005][1005],f[1005][1005];
char s[1005],t[1005];
vector<pair<int,int> > q[2],ans;
void solve(int x,int y){
if(!x&&!y)
return ;
if(f[x][y])
q[a[x+y]<=b[x]].emplace_back(make_pair(a[x+y],b[x])),solve(x-1,y);
else
q[a[x+y]<=c[y]].emplace_back(make_pair(a[x+y],c[y])),solve(x,y-1);
}
int main(){
read();
n=read();
C=read();
scanf("%s",s+1);
scanf("%s",t+1);
for(int i=1;i<=n;i++){
if(s[i]=='2')
a[++num]=i;
}
for(int i=1;i<=n;i++){
if(t[i]=='2'){
if(i&1)
b[++num1]=i;
else
c[++num2]=i;
}
}
memset(dp,32,sizeof(dp));
dp[0][0]=0;
for(int i=0;i<=num1;i++){
for(int j=0;j<=num2;j++){
if(i<num1){
int w=dp[i][j]+abs(a[i+j+1]-b[i+1])/2*(C+4)+abs(a[i+j+1]-b[i+1])%2*(C+3);
for(int k=1;k<=j;k++){
w+=(c[k]>b[i+1]);
}
if(dp[i+1][j]>w)
dp[i+1][j]=w,f[i+1][j]=1;
}
if(j<num2){
int w=dp[i][j]+abs(a[i+j+1]-c[j+1])/2*(C+4)+abs(a[i+j+1]-c[j+1])%2*(C+3);
for(int k=1;k<=i;k++){
w+=(b[k]>c[j+1]);
}
if(dp[i][j+1]>w)
dp[i][j+1]=w,f[i][j+1]=0;
}
}
}
solve(num1,num2);
for(int i=0;i<2;i++){
sort(q[i].begin(),q[i].end());
}
reverse(q[1].begin(),q[1].end());
for(auto i:q[1]){
int st=i.first,ed=i.second;
while(st+1<ed){
ans.emplace_back(make_pair(st,st+2));
st+=2;
}
if(st!=ed)
ans.emplace_back(make_pair(st,st+1));
}
for(auto i:q[0]){
int st=i.first,ed=i.second;
while(st-1>ed){
ans.emplace_back(make_pair(st-2,st));
st-=2;
}
if(st!=ed)
ans.emplace_back(make_pair(st-1,st));
}
write(ans.size());
putchar('\n');
for(auto i:ans){
write(i.first);
putchar(' ');
write(i.second);
putchar('\n');
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 0
Wrong Answer
time: 0ms
memory: 9352kb
input:
5 2 11221 21112
output:
0
result:
wrong answer invalid plan.