HDU5803 Zhu’s Math Problem (数位DP)
来源:互联网 发布:ojbdk是什么意思网络 编辑:程序博客网 时间:2024/06/06 06:57
题目链接:点击此处查看
题目大意:
给出
题解:
这题有三种解法。一种是大胆瞎猜推测答案是关于
第二种暴力推公式,也可以得到一个答案的多项式 - -…推不出来..
第三种是数位DP,这个数位DP比较神奇,没写过这种数位DP。但是该题也有比较明显的特点,是给出特定区间,统计满足条件的数(四元组)的个数。同时对四个数进行数位DP,需要记录的状态是每位
通常在写数位DP的时候,为了记忆化数据对每一次查询都能够使用,我们会设置一个fp标记到当前位为止是否是上界的值。在这里我们需要设置4个上界。4数字个都不为上界的情况实际上是比较少的。因此如果只记忆化非上界的值,会有大量的重复运算。在这里只能放弃记忆化对所有查询的贡献,而要多开四维状态来记录每个数是否处于上界,这四维状态可以压位处理。因为DP数组只记录特定的查询的DP值,所以每次查询的时候需要对DP数组重新初始化。
#include <iostream>#include <cstdio>#include <algorithm>#include <vector>#include <cstring>#include <cstdlib>#include <string>#include <cmath>#include <set>#include <map>#include <bitset>using namespace std;typedef long long ll;const int mod = 1000000007;const double eps = 1e-6;const int inf = 0x3f3f3f3f;const ll INF = 100000000000000000ll;const int MAXN = 100010;const int MAXM = 300030;int d1[67],d2[67],d3[67],d4[67];int dp[67][4][4][16];int dfs(int len,int s1,int s2,int mask){ if(!len){ if(s1>0&&s2>=0) return 1; return 0; } if(dp[len][s1+1][s2+1][mask] != -1) return dp[len][s1+1][s2+1][mask]; int a,b,c,d; a = (mask&8)?d1[len]:1; b = (mask&4)?d2[len]:1; c = (mask&2)?d3[len]:1; d = (mask&1)?d4[len]:1; int ret = 0; for(int i = 0;i <= a;i++){ for(int j = 0;j <= b;j++){ for(int k = 0;k <= c;k++){ for(int l = 0;l <= d;l++){ int t1 = s1*2,t2 = s2*2,t = 0; t1 += i+k-j-l; t2 += i+l-j-k; if(t1<-1||t2<-1){ continue; } if(t1>1) t1 = 2; if(t2>1) t2 = 2; if(i==a) t|=8; if(j==b) t|=4; if(k==c) t|=2; if(l==d) t|=1; ret += dfs(len-1,t1,t2,mask&t); ret %= mod; } } } } return dp[len][s1+1][s2+1][mask] = ret;}int f(ll a,ll b,ll c,ll d){ int len = 0; while(a||b||c||d){ d1[++len] = a&1; d2[len] = b&1; d3[len] = c&1; d4[len] = d&1; a>>=1; b>>=1; c>>=1; d>>=1; } return dfs(len,0,0,15);}int main(){ int T; //freopen("1011.in","r",stdin); //freopen("out","w",stdout); cin>>T; ll a,b,c,d; while(T--){ memset(dp,-1,sizeof(dp)); scanf("%I64d%I64d%I64d%I64d",&a,&b,&c,&d); printf("%d\n",f(a,b,c,d)); //printf("cnt = %I64d nn = %I64d\n",cnt,nn); } return 0;}
- HDU5803 Zhu’s Math Problem (数位DP)
- HDU 5803 Zhu's Math Problem(数位DP)
- 2016多校训练Contest6: 1011 Zhu’s Math Problem hdu5803
- hdu 5803 Zhu’s Math Problem (2016多校第六场1011)数位dp
- Hdu 5803 Zhu’s Math Problem(非记忆化数位dp)
- hihoCoder 1259 A Math Problem 数位dp
- hihoCoder 1259 A Math Problem 数位dp
- uvalive7271(A Math Problem) 数位dp
- [POJ3986]Math teacher's homework && 数位DP
- hdu 5435 A serious math problem(数位dp)
- hdu 5435 A serious math problem 数位dp
- hihoCoder 1259 A Math Problem(数位dp)
- Hihocoder 1259 A Math Problem(数位DP+公式推导)
- UVALive 7271 A Math Problem 【数位dp计数】
- 数位dp-hdu-3693-Math teacher's homework
- uva 1489 - Math teacher's homework(数位dp)
- hdu 3693 Math teacher's homework(数位dp)
- HDU 3693 Math teacher's homework (数位DP?)
- 欢迎使用CSDN-markdown编辑器
- caffe源码阅读-插曲-math_function.cpp
- 动态库和静态库的导出
- Windows下对进程的一些操作
- python编程(1):函数的参数
- HDU5803 Zhu’s Math Problem (数位DP)
- iOS 对数组中的对象进行排序
- 初学HTML5--CSS样式(四)
- HDOJ 1231 最大连续子序列
- 123
- Java反射第二课 动态加载类
- toj 4608 Ball in a Rectangle
- eclipse开发环境搭建
- 同步和互斥的关系