UVA 11645 Bits
来源:互联网 发布:后缀表达式c语言算法 编辑:程序博客网 时间:2024/05/29 16:49
这题写的真是无比蛋疼啊,刚开始看,感觉像是数位dp,想了想,应该能做,那就搞吧,费了半天劲终于写完了,数据看起来也没啥问题了,交上去发现wa了,后来发现数据非常大的话就会超出long long的范围,这意思是要写高精啊,当时就郁闷了,没办法,又写了半天大整数加法和乘法,为了把之前的代码改成大整数的又弄了一会儿,写完真是累死人了。。。唉,这代码写的真是不忍直视,凑合看吧……
对于一个数,先将其转换为二进制。每个数可以用若干个模板和前缀表示,用f(m,b,d)表示这个数的结果,则m表示它的前缀中有多少个Adjacent Bits,b表示它前一位是1还是0,d表示这个数有多少个*,其中*可以表示0和1的任意一个数,比如110就可以用**、10*、110表示,分别对应f(0,0,2)、f(0,0,1)、f(1,0,0),这样就可以写出递推公式:
f(m,b,d)=f(m+(b==1?1:0),1,d-1)+f(m,0,d-1);
用dp[m][b][d]表示状态,将搜过的状态直接返回。
附上代码:
#include <iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<map>#include<queue>#include<stack>#include<cmath>#include<vector>#define inf 0x3f3f3f3f#define Inf 0x3FFFFFFFFFFFFFFFLL#define eps 1e-9#define pi acos(-1.0)using namespace std;typedef long long ll;struct BigInt //自己写的大整数,比较挫,可以无视{ int num[50]; int len; void clear() { for(int i=0;i<50;++i) num[i]=0; len=1; } void getBigInt(ll n) { clear(); len=0; while(n!=0) { num[len++]=n%10; n/=10; } if(len==0) len=1; } void getBigInt(int n) { ll m=(ll)n; getBigInt(m); } BigInt operator + (const BigInt a)const { int n=max(len,a.len); BigInt c; c.clear(); c.len=0; int jinwei=0; int tp; for(int i=0;i<n;++i) { tp=a.num[i]+num[i]+jinwei; c.num[c.len++]=tp%10; jinwei=tp/10; } while(jinwei!=0) { c.num[c.len++]=jinwei%10; jinwei/=10; } return c; } BigInt operator * (const BigInt a) const { int m=a.len; int n=len; BigInt c; c.clear(); c.len=0; int bs=0,w=0,jinwei=0,tp; for(int i=0;i<m;++i) { jinwei=0; w=0; for(int j=0;j<n;++j) { tp=a.num[i]*num[j]+jinwei+c.num[bs+w]; c.num[bs+w]=tp%10; jinwei=tp/10; w++; } while(jinwei!=0) { c.num[bs+w]=jinwei%10; jinwei/=10; w++; } c.len=max(c.len,bs+w); bs++; } while(c.num[c.len-1]==0&&c.len>1) c.len--; return c; }};BigInt dp[70][2][70];BigInt pp[70];int nu[100];BigInt f(int m,int b,int d){ BigInt tp,td; tp.clear(); td.clear(); if(d<0) return tp; tp.getBigInt(m); if(d==0) return tp; if(d==1) { td.getBigInt(b==1?1:0); return td+pp[d]*tp; } if(d==2) { td.getBigInt(b==1?3:1); return td+pp[d]*tp; } if(dp[m][b][d].len>0) return dp[m][b][d]; dp[m][b][d].clear(); dp[m][b][d]=dp[m][b][d]+f(m+(b==1?1:0),1,d-1); dp[m][b][d]=dp[m][b][d]+f(m,0,d-1); return dp[m][b][d];}BigInt slove(int n){ int m=0,b=0,d=n; BigInt res; res.clear(); //res+=f(0,0,n-1); for(int i=0;i<n;++i) { d--; if(nu[i]==1) { res=res+f(m,0,d); m+=(b==1)?1:0; b=1; } else { b=0; } } BigInt tp; tp.getBigInt(m); res=res+tp; return res;}void Init(){ ll z=1; pp[0].getBigInt(z); for(int i=1;i<=63;++i) { z=z<<1; pp[i].getBigInt(z); } for(int i=0;i<70;++i) { for(int j=0;j<2;++j) { for(int k=0;k<70;++k) { dp[i][j][k].len=-1; } } }}int main(){ //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); Init(); int tcase=0; ll x; while(cin>>x) { if(x<0) break; tcase++; int len=0; while(x!=0) { nu[len++]=x%2; x=x>>1; } int temp; for(int i=0;i<len/2;++i) { temp=nu[i]; nu[i]=nu[len-i-1]; nu[len-i-1]=temp; } BigInt res=slove(len); cout<<"Case "<<tcase<<": "; for(int i=res.len-1;i>=0;--i) cout<<res.num[i]; cout<<endl; } return 0;}
- uva 11645 Bits
- UVA 11645 Bits
- UVA - 11645 Bits
- UVA 11645 - Bits(数论+计数问题)
- uva 11645 - Bits(计数问题+高精度)
- Uva - 12545 - Bits Equalizer
- uva 12545Bits Equalizer
- uva 12545 - Bits Equalizer
- UVA 12545 - Bits Equalizer
- UVA 12545 Bits Equalizer
- Bits Equalizer UVA
- Bits Equalizer UVA
- Uva 11645 - Bits 解题报告(递推+大数)
- UVa 11645 Bits(计数原理+高精度)
- UVa 446 - Kibbles "n" Bits "n" Bits "n" Bits
- UVA - 12545 Bits Equalizer 贪心
- UVA 12545(p253)----Bits Equalizer
- uva 12545 Bits Equalizer(贪心)
- linux lab4 一些错误集锦
- 获取IOS应用列表
- STM8AF6269学习-定时器(1)
- Logica SMPP 源代码修改
- C#得到三个数的最大值
- UVA 11645 Bits
- 满足现状才是我们真正的错误
- 字符串面试题(一)字符串逆序
- 关于Java内存泄露的问题
- 无监督机器学习的kmeans思想介绍
- 用栈实现四则运算
- C++中函数重载、覆盖与隐藏的区别
- javascript——创建对象的方式
- 队列操作