P4574 [CQOI2013]二進位制A+B
阿新 • • 發佈:2018-12-20
據說這題有構造的方法然而不是很看的懂po姐寫的->這裡
於是只好數位dp了……設\(f[i][j][k][l][0/1]\)表示考慮到第\(i\)位,\(a\)中選了\(j\)個\(1\),\(b\)中選了\(k\)個\(1\),\(c\)中選了\(l\)個\(1\),\(0/1\)表示該位是否進位,然後直接數位dp就好了
//minamoto #include<bits/stdc++.h> #define R register #define inf 0x3f3f3f3f3f3f3f3f #define ll long long #define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i) #define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i) #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v) template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;} using namespace std; const int N=35; ll f[N][N][N][N][2]; int cntx,cnty,cntz,n,a,b,c,cnt; int main(){ // freopen("testdata.in","r",stdin); scanf("%d%d%d",&a,&b,&c);n=max(a,max(b,c)); while(a)cntx+=a&1,a>>=1; while(b)cnty+=b&1,b>>=1; while(c)cntz+=c&1,c>>=1; while(n)++cnt,n>>=1; memset(f,0x3f,sizeof(f)),f[0][0][0][0][0]=0; fp(i,0,cnt-1)fp(j,0,min(i,cntx))fp(k,0,min(i,cnty))fp(l,0,min(i,cntz)) fp(x,0,1)fp(y,0,1)fp(z,0,1) if(x+y+z&1)cmin(f[i+1][j+x][k+y][l+1][x+y+z>>1],f[i][j][k][l][z]+(1<<i)); else cmin(f[i+1][j+x][k+y][l][x+y+z>>1],f[i][j][k][l][z]); if(f[cnt][cntx][cnty][cntz][0]==inf)return puts("-1"),0; return printf("%lld\n",f[cnt][cntx][cnty][cntz][0]),0; }