zoukankan      html  css  js  c++  java
  • P4574 [CQOI2013]二进制A+B

    https://www.luogu.com.cn/problem/P4574

    就是数位 dp,用 (f(now,i,j,k,CF)) 表示第 (now) 位,(a,b,c) 的一的个数分别用了 (i,j,k) 个,(CF) 表示有没有进位

    然后注意这里应该用顺推,而不是那种记忆化搜索的形式,通过样例就能知道如果写成记忆化搜索,某一个 (f) 的值可能被并不是最优的一个 (c) 来更新了,又因为是记忆化,所以就把这个值当成了最终结果,出现错误

    好像还有一种更妙的构造方式,但并不会

    #include<cstdio>
    #include<algorithm>
    #include<iostream>
    #include<cmath>
    #include<map>
    #include<iomanip>
    #include<cstring>
    #define reg register
    #define EN puts("")
    inline long long read(){
    	register long long x=0;register int y=1;
    	register char c=std::getchar();
    	while(c<'0'||c>'9'){if(c=='-') y=0;c=std::getchar();}
    	while(c>='0'&&c<='9'){x=x*10+(c^48);c=std::getchar();}
    	return y?x:-x;
    }
    #define INF 0x3f3f3f3f3f3f3f3f
    long long f[33][33][33][33][2];
    int numa,numb,numc,nummax;
    inline void min(long long &a,long long b){(a>b)&&(a=b);}
    int main(){
    	long long a=read(),b=read(),c=read();
    	int tot=0;
    	while(a) numa+=(a&1),a>>=1,tot++;
    	nummax=tot;tot=0;
    	while(b) numb+=(b&1),b>>=1,tot++;
    	nummax=std::max(nummax,tot);tot=0;
    	while(c) numc+=(c&1),c>>=1,tot++;
    	nummax=std::max(nummax,tot);
    	std::memset(f,0x3f,sizeof f);
    	f[0][0][0][0][0]=0;
    	for(reg int now=0;now<nummax;now++){
    		for(reg int i=0;i<=numa;i++)for(reg int j=0;j<=numb;j++)for(reg int k=0;k<=numc;k++){
    			if(f[now][i][j][k][0]!=INF){
    				min(f[now+1][i][j][k][0],f[now][i][j][k][0]);
    				if(i<numa&&k<numc) min(f[now+1][i+1][j][k+1][0],f[now][i][j][k][0]+(1<<now));
    				if(j<numb&&k<numc) min(f[now+1][i][j+1][k+1][0],f[now][i][j][k][0]+(1<<now));
    				if(i<numa&&j<numb) min(f[now+1][i+1][j+1][k][1],f[now][i][j][k][0]);
    			}
    			if(f[now][i][j][k][1]!=INF){
    				if(k<numc) min(f[now+1][i][j][k+1][0],f[now][i][j][k][1]+(1<<now));
    				if(i<numa) min(f[now+1][i+1][j][k][1],f[now][i][j][k][1]);
    				if(j<numb) min(f[now+1][i][j+1][k][1],f[now][i][j][k][1]);
    				if(i<numa&&j<numb&&k<numc) min(f[now+1][i+1][j+1][k+1][1],f[now][i][j][k][1]+(1<<now));
    			}
    		}
    	}
    	printf("%lld",f[nummax][numa][numb][numc][0]==INF?-1:f[nummax][numa][numb][numc][0]);
    	return 0;
    }
    
  • 相关阅读:
    iscroll.js & flipsnap.js
    IE8’s Substr() Bug
    chrome扩展,如何阻止浏览自动关闭桌面通知.
    临时邮箱
    多个显示器, window.open的定位
    页面刷新
    PipelineDB Install and Test
    CitusDB UPSERT
    Kafka部署
    ambari-cassandra-service
  • 原文地址:https://www.cnblogs.com/suxxsfe/p/13661100.html
Copyright © 2011-2022 走看看