【Codeforces866E_CF866E】Hex Dyslexia(Structure & DP)
It's my first time to write a blog in EnglishChinglish, so it may be full of mistakes in grammar.
Problem:
Analysis:
First, we determine \(S\geq T\), then \(S-T=A\), where \(A\) is the known number, and \(S\) is shuffled from \(T\). Then move \(T\) to the right so we have \(S=T+A\).
Think about how to calculate \(T+A\) in writing. If undo all Jinwei (This is Chinese Pinyin. I don't know how to express it in English. Jinwei means if \(T_i+A_i\) is not less than \(16\) in hex, then subtract \(16\) from it and add \(1\) to \(S_{i+1}\)), then for every digit, it's \(T_i+A_i=S'_i\) (\(S'_i\) can be greater than \(15\) now). Now, \(\sum T_i + \sum A_i = \sum S'_i\). But because of \(S\) is shuffled from \(T\), \(\sum T_i\) should be equal to \(\sum S_i\). Fortunately, every Jinwei can subtract \(15\) from \(\sum S'_i\), because Jinwei is subtracting \(16\) from \(S'_i\) and add \(1\) to \(S'_{i+1}\). Thus, possible \(S\) and \(T\) exist only when \(A\) is divisible by \(15\).
If \(A\) is divisible by \(15\), \(\frac{\sum A_i}{15}\) is the times that Jinwei happens. We can determine whether a Jinwei happens on a dight one after another. Jinwei can't happen on the hightest dight, so the total number of ways that exactly \(\frac{\sum A_i}{15}\) Jinweis happen is \(C_{|T|-1}^{\frac{\sum A_i}{15}}\), where \(|T|\) is the length of \(T\). It's not greater than \(C_{13}^{\lfloor \frac{13}{2} \rfloor}=1716\).
Now we have determined which digits Jinweis happen on, so we can offset the effect of Jinweis by changing \(A\). Specifically, if a Jinwei happens on the digit \(i\), so that \(T_i+A_i-16=S_i\) and \(T_{i+1}+A_{i+1}+1=S_{i+1}\), we can subtract \(16\) from \(A_i\) and add \(1\) to \(A_{i+1}\) ( \(A_i\) now can be more than \(15\) or less than \(0\) ) , then for every \(i\), there's \(T_i+A_i=S_i\). In this way, every digit will be independent. (From now on, \(A\) is the changed one. )
Let's try to structure a possible answer. It should be noticed that now there's no Jinwei happens, or the answer is invalid. An useful fact is, there's at least one \(T_i\) that is \(0\), or subtract the minimum in \(T\) from each \(T_i\) and \(S_i\), so that every \(T_i+A_i=S_i\) is valid as well, but we get a less \(T\). To minimize \(T\), let's put \(0\) on the highest digit directly.
Define \(f[S]\) is the minimum of \(T\) when the digits in the set \(S\) have been decided. Because the number on the highest digit must be \(0\) and there's no need to consider that digit, \(S\) is not contain the highest digit. Each time we decide put \(a\) on a digit \(i\), we'll get a new number \(a+A_i\) that waiting to be put. This new number after deciding all digits in the set \(S\) is exactly \(\sum_{i\in S}A_i+A_{|T|-1}\) ( \(|T|-1\) is the highest digit) , because the first number we put is \(0\), and then we get \(A_{|T|-1}\); the second number we put is \(A_{|T|-1|}\) on digit \(i\) and we get \(A_{|T|-1}+A_i\) and so on. In the end, because of our way to change \(A_i\), \(\sum A_i\) must be \(0\), and \(0\) has already been put on the highest digit. How lucky we are!
Now the problem is easy. For every \(S\), choose a digit \(i\) and try to put the new number \(sum[S]\) (in the code it's called like that, but I don't know why, maybe because Tzz is a mouther) on it.
For more details, please read the code.
Code:
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cctype>
#include <set>
using namespace std;
namespace zyt
{
template<typename T>
inline bool read(T &x)
{
char c;
bool f = false;
x = 0;
do
c = getchar();
while (c != EOF && c != '-' && !isdigit(c));
if (c == EOF)
return false;
if (c == '-')
f = true, c = getchar();
do
x = x * 10 + c - '0', c = getchar();
while (isdigit(c));
if (f)
x = -x;
return true;
}
inline bool read(char &c)
{
do
c = getchar();
while (c != EOF && !isgraph(c));
return c != EOF;
}
template<typename T>
inline void write(T x)
{
static char buf[20];
char *pos = buf;
if (x < 0)
putchar('-'), x = -x;
do
*pos++ = x % 10 + '0';
while (x /= 10);
while (pos > buf)
putchar(*--pos);
}
inline void write(const char *const s)
{
printf("%s", s);
}
typedef long long ll;
const int N = 15, D = 16, INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3fLL;
int len, arr[N], sum[1 << N];
ll ans = LINF, dp[1 << N];
inline bool check(const int a, const int p)
{
return a & (1 << p);
}
void solve()
{
memset(sum, 0, sizeof(int[1 << len]));
memset(dp, INF, sizeof(ll[1 << len]));
for (int i = 0; i < (1 << (len - 1)); i++)
{
sum[i] = arr[len - 1];
for (int j = 0; j < len - 1; j++)
if (check(i, j))
sum[i] += arr[j];
}
dp[0] = 0;
for (int i = 0; i < (1 << (len - 1)); i++)
{
if (sum[i] < 0 || sum[i] >= D || dp[i] > ans || dp[i] == LINF)
continue;
for (int j = 0; j < len - 1; j++)
if (!check(i, j))
dp[i | (1 << j)] = min(dp[i | (1 << j)], dp[i] + ((ll)sum[i] << (j << 2)));
}
ans = min(ans, dp[(1 << (len - 1)) - 1]);
;
}
void dfs(const int pos, const int rest)
{
if (pos < 0)
{
if (!rest)
solve();
return;
}
dfs(pos - 1, rest);
if (pos && rest)
{
++arr[pos], arr[pos - 1] -= D;
dfs(pos - 1, rest - 1);
--arr[pos], arr[pos - 1] += D;
}
}
int work()
{
char c;
while (read(c))
{
if (isdigit(c))
arr[len++] = c - '0';
else
arr[len++] = c - 'a' + 10;
}
reverse(arr, arr + len);
int sum = 0;
for (int i = 0; i < len; i++)
sum += arr[i];
if (sum % (D - 1))
{
write("NO");
return 0;
}
dfs(len - 1, sum / (D - 1));
if (ans == LINF)
write("NO");
else
{
static char buf[20];
char *pos = buf;
while (len--)
*pos++ = ((ans % D < 10) ? ans % D + '0' : ans % D - 10 + 'a'), ans /= D;
while (pos > buf)
putchar(*--pos);
}
return 0;
}
}
int main()
{
return zyt::work();
}
【Codeforces866E_CF866E】Hex Dyslexia(Structure & DP)的更多相关文章
- 【ACM】不要62 (数位DP)
题目:http://acm.acmcoder.com/showproblem.php?pid=2089 杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer).杭州交通管理局经常会扩充一些的士车牌照,新 ...
- 【BalticOI2003】Gem 题解(树形DP)
题目大意: 给树上每一个结点赋值(值为正整数),要求相邻结点的权值不能相同.问树上最小权值和.$n\leq 10000$. ------------------------- 设$f[i][j]$表示 ...
- 【UVA12093】Protecting Zonk (树形DP)
题意: 给定一个有n个节点的无根树,有两种装置A和B,每种都有无限多个.在某个节点X使用A装置需要C1的花费,并且此时与节点X相连的边都被覆盖.在某个节点X使用B装置需要C2的花费,并且此时与节点X相 ...
- 【UVA1379】Pitcher Rotation (贪心+DP)
题意: 你经营者一直棒球队.在接下来的g+10天中有g(3<=g<=200)场比赛,其中每天最多一场比赛.你已经分析出你的n(5<=n<=100)个投手中每个人对阵所有m个对手 ...
- 【51nod1299】监狱逃离(树形DP)
点此看题面 大致题意: 在一棵树中有\(N\)条边连接\(N+1\)个节点,现在已知这棵树上的\(M\)个节点,要求封住最少的节点,使这\(M\)个节点中的任意一个节点无法到达叶子节点,若能办到输出最 ...
- 【Luogu】P2657windy数(数位DP)
题目链接 正式迈入了数位DP的大门…… 心情激动 (看我立个flag,我如果专攻数位DP的话,到wc之前就会有秒数位DP蓝题的能力) 数位DP讲解链接 讲的非常详细,良心博客.比我写的博客加在一起还要 ...
- 【Luogu】P3174毛毛虫(树形DP)
题目链接 树形DP水题,设f[x][0]是以x为根的子树,内部只有半条链(就是链的两个端点一个在子树里,一个不在子树里)的最大值,f[x][1]是以x为根的子树,内部有一条完整的链(选两个内部的子树作 ...
- 【bzoj1040】骑士[ZJOI2008](树形dp)
题目传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1040 这道题,很明显根据仇恨关系构造出的图形是一堆环套树.如果是普通的树,就可以马上裸树 ...
- 【CF1015F】Bracket Substring(字符串DP)
题意:给定一个只由左右括号组成的字符串s,问长度为2*n的包含它的合法括号序列方案数,答案对1e9+7取模 1≤n≤100,1≤|s|≤200 思路:暴力预处理出s的每个前缀[0..i]后加左右括号分 ...
随机推荐
- poj 3744 Scout YYF I(递推求期望)
poj 3744 Scout YYF I(递推求期望) 题链 题意:给出n个坑,一个人可能以p的概率一步一步地走,或者以1-p的概率跳过前面一步,问这个人安全通过的概率 解法: 递推式: 对于每个坑, ...
- Codeforces Round #235 (Div. 2)
A. Vanya and Cards time limit per test 1 second memory limit per test 256 megabytes input standard i ...
- python——正则表达式的理解
概念:又称规则表达式,常用来检索.替换符合某个规则的文本. 理解:特殊字符--------->规则---------->过滤字符串 目的:1.匹配给定的字符串,2.从字符串中过滤出我们需要 ...
- 互斥的数(codevs 1553)
题目描述 Description 有这样的一个集合,集合中的元素个数由给定的N决定,集合的元素为N个不同的正整数,一旦集合中的两个数x,y满足y = P*x,那么就认为x,y这两个数是互斥的,现在想知 ...
- 别墅房间 CodeVS原创
时间限制: 1 s 空间限制: 64000 KB 题目等级 : 青铜 Bronze 题目描述 Description 小浣熊松松到他的朋友家别墅去玩,发现他朋友的家非常大,而且布局很奇怪.具体来说,朋 ...
- git远程上传文件
[第一步]建立先仓库 第一步的话看一般的提示就知道了,在github新建一个repository(谷歌可以解决),都是可视化的界面操作,所以难度不大.或者看这里:https://help.github ...
- 进入DRF和ANGULAR的整合学习,这三篇入门内容一定要学好的
看来,DJANGO的模板功能是无法用啦, 学着用ANGLUAR的SERVICE,MODULE,CONTROLLER啦... http://engineroom.trackmaven.com/blog/ ...
- 如何取消codeblocks对msvcr100.dll的依赖?
用VS2010或是codeblocks开发的程序,在开发之外的机器上,可能会提前缺少msvcr100.dll之类的文件. 可以用如何设置,取消其对库文件的依赖. 当然,还要注意创建程序的类型.(补) ...
- - > 网络流(【最大流】草地排水模板题)
1993 草地排水 USACO 时间限制: 2 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Description 在农夫约翰的农场上,每 ...
- MyBatis3-实现单表数据的增删查改
继续前一篇文章http://www.cnblogs.com/EasonJim/p/7050710.html所示的例子,返回的是单个实体,而接下来将进行列表的返回等操作: 一.查询列表 查询出列表,也就 ...