1733D1
题目大意:给出两个长度为n的01串,每次能选择两个位置进行取反,相邻的位置取反代价为x,不相邻则为y,问让其中一串变成另一串的最小代价
初遇想法
对于两个串上01不同的位置可以直接发现
相邻代价为$min$($x$,$y/times2$)
不相邻代价为$min$($x/times$两点距离,$y$)
并且若01不同的位置是奇数显然无解
由于直接忽略了题给的$x$和$y$的大小条件,以至于我陷入了D2的思考。
考虑贪心,每两个点直接进行代价的判断
显然最后为了纠正这个错误的想法花了相当大的力气
further
根据题给条件,发现出题人希望让我们去多使用不相邻的两点
反思和提醒之后发现,把视线只放在两点是很局限的一种判断
只要超过三个点,我们可以直接跨点构造出不相邻
结论
特判长度是否为2,即无法构造不不相邻
否则全部构造成不相邻
代码如下
#include <bits/stdc++.h>
using namespace std;
int a[100000],b[100000];
vector<int> s;
int read()
{
int ret(0);
char ch=getchar();
while (ch!='0'&&ch!='1') ch=getchar();
return ch-48;
}
int main()
{
int t;
scanf("%d",&t);
while (t--)
{
s.clear();
long long n,x,y;
scanf("%lld%lld%lld",&n,&x,&y);
for (int i=1;i<=n;i++) a[i]=read();
for (int i=1;i<=n;i++) b[i]=read();
for (int i=1;i<=n;i++)
if (a[i]!=b[i]) s.push_back(i);
int len=s.size()-1;long long ans(0);
if ((len+1)%2==0)
{
if (len+1>2) printf("%lld\n",y*(len+1)/2);
else
{
if (len+1==0) printf("0\n");
else if (s[0]+1==s[1]) printf("%lld\n",min(y*2,x));
else printf("%lld\n",y);
}
}
else printf("-1\n");
}
return 0;
}
1733D2
$n^3dp$很显然
$n^3$的问题在于枚举断点,联系上一题,长度大于4,就可以强行构造不相邻,所以断点是长度为4的时候
$n^2$dp即可
#include <bits/stdc++.h>
using namespace std;
int a[100000],b[100000];
vector<int> s;
long long x,y;
long long dp[5010][5010];
long long solve(int a,int b)
{
if (a+1==b) return min(x,y*2);
else return min(x*(b-a),y);
}
int read()
{
int ret(0);
char ch=getchar();
while (ch!='0'&&ch!='1') ch=getchar();
return ch-48;
}
int main()
{
int t;
scanf("%d",&t);
while (t--)
{
s.clear();
long long n;
scanf("%lld%lld%lld",&n,&x,&y);
for (int i=1;i<=n;i++) a[i]=read();
for (int i=1;i<=n;i++) b[i]=read();
s.push_back(0);
for (int i=1;i<=n;i++)
if (a[i]!=b[i]) s.push_back(i);
int len=s.size()-1;
for (int i=1;i<=len;i++)
for (int j=1;j<=len;j++)
dp[i][j]=0x3f3f3f3f3f3f3f3f;
//printf("len=%d\n",len);
if (len==0) printf("0\n");
else
{
if (len&1) printf("-1\n");
else
{
for (int i=1;i<len;i++)
dp[i][i+1]=solve(s[i],s[i+1]);
// for (int i=1;i<len;i++)
// printf("%d %d %lld\n",i,i+1,dp[i][i+1]);
for (int i=3;i<len;i+=2)
{
for (int l=1;l<=len-i;l++)
{
int r=l+i;
//printf("%d %d %dQQQ\n",l,r,i);
dp[l][r]=min(dp[l][r-2]+solve(s[r-1],s[r]),dp[l+2][r]+solve(s[l],s[l+1]));
dp[l][r]=min(dp[l][r],dp[l+1][r-1]+solve(s[l],s[r]));
dp[l][r]=min(dp[l][r],y*(r-l+1)/2);
if (len>=5) dp[l][r]=min(dp[l][l+3]+dp[l+4][r],dp[l][r]);
}
}
printf("%lld\n",dp[1][len]);
}
}
}
return 0;
}
标签:ch,return,int,long,解题,D2,1733D1,dp,lld
From: https://www.cnblogs.com/by-w/p/16716969.html