It's my first time to write a blog in EnglishChinglish, so it may be full of mistakes in grammar.

Problem:

Codeforces866E

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)的更多相关文章

  1. 【ACM】不要62 (数位DP)

    题目:http://acm.acmcoder.com/showproblem.php?pid=2089 杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer).杭州交通管理局经常会扩充一些的士车牌照,新 ...

  2. 【BalticOI2003】Gem 题解(树形DP)

    题目大意: 给树上每一个结点赋值(值为正整数),要求相邻结点的权值不能相同.问树上最小权值和.$n\leq 10000$. ------------------------- 设$f[i][j]$表示 ...

  3. 【UVA12093】Protecting Zonk (树形DP)

    题意: 给定一个有n个节点的无根树,有两种装置A和B,每种都有无限多个.在某个节点X使用A装置需要C1的花费,并且此时与节点X相连的边都被覆盖.在某个节点X使用B装置需要C2的花费,并且此时与节点X相 ...

  4. 【UVA1379】Pitcher Rotation (贪心+DP)

    题意: 你经营者一直棒球队.在接下来的g+10天中有g(3<=g<=200)场比赛,其中每天最多一场比赛.你已经分析出你的n(5<=n<=100)个投手中每个人对阵所有m个对手 ...

  5. 【51nod1299】监狱逃离(树形DP)

    点此看题面 大致题意: 在一棵树中有\(N\)条边连接\(N+1\)个节点,现在已知这棵树上的\(M\)个节点,要求封住最少的节点,使这\(M\)个节点中的任意一个节点无法到达叶子节点,若能办到输出最 ...

  6. 【Luogu】P2657windy数(数位DP)

    题目链接 正式迈入了数位DP的大门…… 心情激动 (看我立个flag,我如果专攻数位DP的话,到wc之前就会有秒数位DP蓝题的能力) 数位DP讲解链接 讲的非常详细,良心博客.比我写的博客加在一起还要 ...

  7. 【Luogu】P3174毛毛虫(树形DP)

    题目链接 树形DP水题,设f[x][0]是以x为根的子树,内部只有半条链(就是链的两个端点一个在子树里,一个不在子树里)的最大值,f[x][1]是以x为根的子树,内部有一条完整的链(选两个内部的子树作 ...

  8. 【bzoj1040】骑士[ZJOI2008](树形dp)

    题目传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1040 这道题,很明显根据仇恨关系构造出的图形是一堆环套树.如果是普通的树,就可以马上裸树 ...

  9. 【CF1015F】Bracket Substring(字符串DP)

    题意:给定一个只由左右括号组成的字符串s,问长度为2*n的包含它的合法括号序列方案数,答案对1e9+7取模 1≤n≤100,1≤|s|≤200 思路:暴力预处理出s的每个前缀[0..i]后加左右括号分 ...

随机推荐

  1. Hdu 4864(Task 贪心)(Java实现)

    Hdu 4864(Task 贪心) 原题链接 题意:给定n台机器和m个任务,任务和机器都有工作时间值和工作等级值,一个机器只能执行一个任务,且执行任务的条件位机器的两个值都大于等于任务的值,每完成一个 ...

  2. 【Codeforces 598D】Igor In the Museum

    [链接] 我是链接,点我呀:) [题意] 题意 [题解] 同一个联通块里面答案都一样. 把每个联通块的答案都算出来 然后赋值就好 [代码] #include <bits/stdc++.h> ...

  3. POJ 1970 The Game

    The Game Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 6886   Accepted: 1763 Descript ...

  4. 为什么Linux下的环境变量要用大写而不是小写

    境变量的名称通常用大写字母来定义.实际上用小写字母来定义环境变量也不会报错,只是习惯上都是用大写字母来表示的. 首先说明一下,在Windows下是不区分大小写的,所以在Windows下怎么写都能获取到 ...

  5. JavaScript实现页面无刷新让时间走动

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  6. What are Unix swap (.swp) files?

    原文: http://www.networkworld.com/article/2931534/it-management/what-are-unix-swap-swp-files.html ---- ...

  7. 从理论到实践,全方位认识DNS(理论篇)

    对于 DNS(Domain Name System) 大家肯定不陌生,不就是用来将一个网站的域名转换为对应的IP吗.当我们发现可以上QQ但不能浏览网页时,我们会想到可能是域名服务器挂掉了:当我们用别人 ...

  8. bootstrap-table方法之:expandRow-collapseRow,展开或关闭当前行数据

    官方演示地址:http://issues.wenzhixin.net.cn/bootstrap-table/methods/expandRow-collapseRow.html <!DOCTYP ...

  9. HTTP的GET和POST请求

    1.GET请求: 格式例如以下: request-line headers blank-line request-body 如图是我用wireshark截的一个GET请求的HTTP首部: GET请求发 ...

  10. keepalived+nginx安装配置

    软件版本号: pcre8.36 ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.36.tar.gz keepalived1.2 ...