hdu5803

题意

给出四个整数 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 .

分析

可以用数位dp解决这个问题。

同时对四个数进行数位dp,采用记忆化搜索的形式,搜索过程中考虑剪枝,考虑到百位数时,如果 a + c - b - d >= 2,那么到十位数时(a + c - b - d 最少也才 -18,而前面到十位数会乘 10 即得到 20)一定满足条件了(加上 a + d - b - c 同理),而 a + c - b - d <= -2 那么到十位数时无论如何都不会满足条件了,可以直接剪枝。

但是每次要有 10 * 10 * 10 * 10 的状态转移,还要考虑优化,将四个数转化成二进制数,再进行 dp,前面的剪枝仍然可用。

code

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll MOD = 1e9 + 7;
int bit[5][65];
ll dp[62][5][5][16];
ll dfs(int l, int acbd, int adbc, int limit)
{
if(l < 0) return acbd > 0 && adbc >= 0;
ll& res = dp[l][acbd + 2][adbc + 2][limit];
if(res != -1) return res;
res = 0;
int up[4];
for(int i = 0; i < 4; i++)
{
up[i] = (limit >> i & 1) ? bit[i][l] : 1;
}
for(int a = 0; a <= up[0]; a++)
{
for(int b = 0; b <= up[1]; b++)
{
for(int c = 0; c <= up[2]; c++)
{
for(int d = 0; d <= up[3]; d++)
{
int acbd_ = acbd, adbc_ = adbc, limit_ = 0;
acbd_ = min(acbd_ * 2 + a + c - b - d, 2);
adbc_ = min(adbc_ * 2 + a + d - b - c, 2);
if(acbd_ <= -2 || adbc_ <= -2) continue;
if(a == up[0] && (limit & 1)) limit_ |= 1;
if(b == up[1] && (limit >> 1 & 1)) limit_ |= 2;
if(c == up[2] && (limit >> 2 & 1)) limit_ |= 4;
if(d == up[3] && (limit >> 3 & 1)) limit_ |= 8;
(res += dfs(l - 1, acbd_, adbc_, limit_)) %= MOD;
}
}
}
}
return res;
}
int main()
{
int T;
for(scanf("%d", &T); T--;)
{
memset(bit, 0, sizeof bit);
memset(dp, -1, sizeof dp);
ll A, B, C, D;
scanf("%lld%lld%lld%lld", &A, &B, &C, &D);
for(int i = 0; i < 62; i++)
{
bit[0][i] = A >> i & 1;
bit[1][i] = B >> i & 1;
bit[2][i] = C >> i & 1;
bit[3][i] = D >> i & 1;
}
printf("%lld\n", dfs(60, 0, 0, 15));
}
return 0;
}

hdu5803的更多相关文章

随机推荐

  1. 日历上添加活动通知(Asp.net)

    <div id="calendar_contain"> </div> <script language="javascript" ...

  2. OutOfMemoryError内存不足

    java.lang.OutOfMemoryError内存不足错误.当可用内存不足以让Java虚拟机分配给一个对象时抛出该错误. 造成此错误的原因有一下几个: 1.内存中加载的数据量过于庞大,如一次从数 ...

  3. [No0000E9]Microsoft Help Viewer 2.3绿色版

    今天没事,提取了一下2017的Microsoft Help Viewer 2.3绿色版,自测没发现什么问题,有问题请后补. 下载地址:http://files.cnblogs.com/files/Ch ...

  4. iOS·UIKit框架注解 & Foundation

  5. [.NET] 《C# 高效编程》(一) - C# 语言习惯

    C# 语言习惯 目录 一.使用属性而不是可访问的数据成员 二.使用运行时常量(readonly)而不是编译时常量(const) 三.推荐使用 is 或 as 操作符而不是强制类型转换 四.使用 Con ...

  6. HTTP笔记

    "你知道当我们在网页浏览器(Web browser)的地址栏中输入 URL 时,Web 页面是如何呈现的吗?" HTTP协议 HTTP协议(HyperText Transfer P ...

  7. .net应用程序中添加chm帮助文档打开显示此程序无法显示网页问题

    在做.net大作业时添加了chm帮助文档结果在打开时显示“此程序无法显示网页问题”,但是把帮助文档拷到别的路径下却显示正常, 经过从网上查找,终于找到了答案: (1).chm文件的路径中不能含有“#” ...

  8. [原创] 绿色单文件封装程序GreenOne V3.0

    1.原理 将包含可执行文件的多个文件 调用Winrar,创建自解压格式压缩文件 设置高级自解压选项中的文本和图标,设置解压后运行的文件为选中的可执行文件. 这种创建单文件封装其实也就是一个Winrar ...

  9. JavaScript ,Python,java,Go系列算法之选择排序

    常见的内部排序算法有:插入排序.希尔排序.选择排序.冒泡排序.归并排序.快速排序.堆排序.基数排序等. 用一张图概括:   选择排序 选择排序是一种简单直观的排序算法,无论什么数据进去都是O(n2) ...

  10. java泛型探索——泛型类

    本文主要讨论一下如何声明泛型类,讨论的范围涉及构造函数.静态成员.内部类. 构造函数 泛型的类型参数首先声明在首部: public class Pair<T,U> { private fi ...