https://www.luogu.com.cn/problem/P4574
设dp[i][j][k][t]表示,当前在第i位(从右往左数),C填了j个,A填了k个,B填了t个的能凑出满足条件的最小的数。
但是这题存在进位,所以我们还要开一维处理进位的情况。注意我们对答案的贡献只考虑手动给C的第i位填1才算贡献。
然后讨论,当前AB两位是否对C位产生进位。
考虑AB两位不进位:
1.A,B都是0,且后一位不进1=>现在这一位就是0
2.A,B都是0,且后一位进1=>现在这一位就是1
3.A,B有一个是1,且后一位不进1=>现在这一位就是1
考虑AB两位进位:
1.AB都是1,且后一位有进位
2.AB一个是1,且后一位有进位
3.AB都是1,且后一个没进位
然后跑记忆化的话方便边界情况
#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=50;
typedef long long LL;
inline LL read(){LL x=0,f=1;char ch=getchar(); while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;}
LL dp[maxn][maxn][maxn][maxn][2];
///注意只有主动填1时这个1才对答案有贡献
bool vis[maxn][maxn][maxn][maxn][2];
LL dfs(LL now,LL c,LL a,LL b,bool en){
if(now==0){
if(c==0&&a==0&&b==0&&en==0) return 0;
else return 1e18;
}
if(vis[now][c][a][b][en]) return dp[now][c][a][b][en];
vis[now][c][a][b][en]=true;
LL res=1e18;
if(en){///该位自身AB对C有进位
if(a&&b) res=min(res,dfs(now-1,c,a-1,b-1,0));
if(a) res=min(res,dfs(now-1,c,a-1,b,1));
if(b) res=min(res,dfs(now-1,c,a,b-1,1));
if(c&&a&&b) res=min(res,dfs(now-1,c-1,a-1,b-1,1)+(1LL<<(now-1)));
}
else{///该位自身AB对C无进位
res=min(res,dfs(now-1,c,a,b,0));
if(c){
res=min(res,dfs(now-1,c-1,a,b,1)+(1LL<<(now-1)));
if(a){
res=min(res,dfs(now-1,c-1,a-1,b,0)+(1LL<<(now-1)));
}
if(b){
res=min(res,dfs(now-1,c-1,a,b-1,0)+(1LL<<(now-1)));
}
}
}
dp[now][c][a][b][en]=res;
return dp[now][c][a][b][en];
}
int main(void){
cin.tie(0);std::ios::sync_with_stdio(false);
LL a,b,c;cin>>a>>b>>c;
LL len1=0;LL len2=0;LL len3=0;
LL tot1=0;LL tot2=0;LL tot3=0;
while(a){ tot1+=(a&1); a>>=1;len1++; }
while(b){ tot2+=(b&1); b>>=1;len2++; }
while(c){ tot3+=(c&1); c>>=1;len3++; }
LL len=max(len1,max(len2,len3));
memset(dp,0x3f3f,sizeof(dp));
dfs(len,tot3,tot1,tot2,0);
if(dp[len][tot3][tot1][tot2][0]>=(1LL<<(len))){
cout<<"-1"<<"\n";
}
else{
cout<<dp[len][tot3][tot1][tot2][0]<<"\n";
}
return 0;
}