hdu5803
来源:互联网 发布:sql去掉重复的数据 编辑:程序博客网 时间:2024/06/14 06:11
题意:
给出A、B、C、D。问有多少(a,b,c,d),满足:
a+c>b+d && a+d≥b+c && 0≤a≤A && 0≤b≤B && 0≤c≤C && 0≤d≤D
T≤1000
0≤A,B,C,D≤10^18
#include<cstring>#include<cstdlib>#include<cstdio>#include<cmath>#include<iostream>#define N 100#define mmod 1000000007#define LL long longusing namespace std;int f[N][2][2][2][2][4][4];int a[N],b[N],c[N],d[N],al,bl,cl,dl,n,ans;void upd(int &x,int y){ x=(x+y)%mmod;}int make(int s,int d){ if(s==2) return 2; if(s==3) { if(d==2) return 0; if(d==1) return 3; return -1; } if(s==1) { if(d==-2) return 0; if(d==-1) return 1; return 2; } if(d==-2) return -1; if(d==-1) return 3; return d;}void dp(){ for(int i=0;i<=n;i++) for(int o1=0;o1<=1;o1++) for(int o2=0;o2<=1;o2++) for(int o3=0;o3<=1;o3++) for(int o4=0;o4<=1;o4++) for(int s1=0;s1<=3;s1++) for(int s2=0;s2<=3;s2++) f[i][o1][o2][o3][o4][s1][s2]=0; f[0][0][0][0][0][0][0]=1; for(int i=0;i<n;i++) for(int o1=0;o1<=1;o1++) for(int o2=0;o2<=1;o2++) for(int o3=0;o3<=1;o3++) for(int o4=0;o4<=1;o4++) for(int s1=0;s1<=3;s1++) for(int s2=0;s2<=3;s2++) { if(f[i][o1][o2][o3][o4][s1][s2]==0) continue; for(int d1=0;d1<=1;d1++) { int t1=o1; if(o1==0 && d1>a[i+1]) continue; if(d1<a[i+1]) t1=1; for(int d2=0;d2<=1;d2++) { int t2=o2; if(o2==0 && d2>b[i+1]) continue; if(d2<b[i+1]) t2=1; for(int d3=0;d3<=1;d3++) { int t3=o3; if(o3==0 && d3>c[i+1]) continue; if(d3<c[i+1]) t3=1; for(int d4=0;d4<=1;d4++) { int t4=o4; if(o4==0 && d4>d[i+1]) continue; if(d4<d[i+1]) t4=1; int h1,h2; h1=make(s1,d1+d3-d2-d4); h2=make(s2,d1+d4-d2-d3); if(h1==-1 || h2==-1) continue; upd(f[i+1][t1][t2][t3][t4][h1][h2],f[i][o1][o2][o3][o4][s1][s2]); } } } } }}int main(){ int z;scanf("%d",&z); while(z--) { n=al=bl=cl=dl=0; LL t;scanf("%lld",&t); while(t) {a[++al]=t%2;t/=2;} for(int i=1;i<=al/2;i++) swap(a[i],a[al-i+1]); n=max(n,al); scanf("%lld",&t); while(t) {b[++bl]=t%2;t/=2;} for(int i=1;i<=bl/2;i++) swap(b[i],b[bl-i+1]); n=max(n,bl); scanf("%lld",&t); while(t) {c[++cl]=t%2;t/=2;} for(int i=1;i<=cl/2;i++) swap(c[i],c[cl-i+1]); n=max(n,cl); scanf("%lld",&t); while(t) {d[++dl]=t%2;t/=2;} for(int i=1;i<=dl/2;i++) swap(d[i],d[dl-i+1]); n=max(n,dl); for(int i=al;i>=1;i--) a[i+n-al]=a[i]; for(int i=1;i<=n-al;i++) a[i]=0; for(int i=bl;i>=1;i--) b[i+n-bl]=b[i]; for(int i=1;i<=n-bl;i++) b[i]=0; for(int i=cl;i>=1;i--) c[i+n-cl]=c[i]; for(int i=1;i<=n-cl;i++) c[i]=0; for(int i=dl;i>=1;i--) d[i+n-dl]=d[i]; for(int i=1;i<=n-dl;i++) d[i]=0; dp(); ans=0; for(int a=0;a<=1;a++) for(int b=0;b<=1;b++) for(int c=0;c<=1;c++) for(int d=0;d<=1;d++) for(int o1=1;o1<=2;o1++) for(int o2=0;o2<=2;o2++) upd(ans,f[n][a][b][c][d][o1][o2]); printf("%d\n",ans); } return 0;}
题解:
一开始觉得是分类讨论,化柿子化得有点想吐。。然后看了题解,说可以数位dp,那就dp吧。。
注意10^4枚举每位太慢,转成二进制后就是2^4的了
0 0
- hdu5803
- HDU5803 Zhu’s Math Problem (数位DP)
- 2016多校训练Contest6: 1011 Zhu’s Math Problem hdu5803
- PHP 使用 openssl 扩展实现公钥加密
- 集群、分布式、负载均衡区别与联系
- win10与ubantu虚拟机之间的文件传递(Network error: Connection refused)
- 安卓的ADT和SDK的区别
- node安装及环境配置
- hdu5803
- React Native 项目(One 【一个】客户端)
- 51nod 1384 全排列
- php单双引号的区别
- 表单验证常用正则表达式
- 文本框仅可接收decimal
- Fragment知识点全解析(二)
- 1602LCD液晶显示
- 三羊献瑞