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. out对象的使用

    out对象的使用 制作人:全心全意 out对象用于在Web浏览器内输出信息,并且管理应用服务器上的输出缓冲区.在使用out对象输出数据时,可以对数据缓冲区进行操作,及时清除缓冲区中的残余数据,为其他的 ...

  2. buf.writeInt8()函数详解

    buf.writeInt8(value, offset[, noAssert]) value {Number} 需要被写入到 Buffer 的字节 offset {Number} 0 <= of ...

  3. python socket实现文件传输(防粘包)

    1.文件传输的要点: 采用iterator(迭代器对象)迭代读取,提高读取以及存取效率: 通过for line in file_handles逐行conn.send(): 2.socket粘包问题: ...

  4. vue中路由

    关于每次点击链接都要刷新页面的问题众所周知,开发单页应用就是因为那丝般顺滑的体验效果,如果每次点击都会刷新页面… 出现这个的原因是因为使用了window.location来跳转,只需要使用使用rout ...

  5. circumferential averaged streamwise velocity in ParaView

    Goal: get a averaged axial velocity in a circular loop (dashed line in the following figure) Steps: ...

  6. sql杂记:一些坑和数据库恢复

    这是一篇纯粹的乱七八糟的笔记...(勿喷)主要记录一下初入SQL坑的杂七杂八的注意事项. 一.先补充下事务的写法: start transaction;#开始事务 --各种事务... commit;# ...

  7. 51nod1128 正整数分组V2

    [题解] 二分一个最大值,check一下分出来的组数是否小于等于k即可. #include<cstdio> #include<algorithm> #define LL lon ...

  8. 威纶通 与 信捷XC\XD系列PLC 通讯

    第一次使用信捷XD系列PLC正式做个项目,用的触摸屏为威纶通的 MT6071iP (注意:下面内容同样适用于 信捷XC系列PLC ,除信捷XC与XD系列编程软件不一样,其余接线设置实测均一样 ) 目前 ...

  9. Microsoft 根证书计划弃用 SHA-1 哈希算法

    Microsoft 根证书计划弃用 SHA-1 哈希算法 微软官方2016年1月12日发布安全通报,自2016年1月1日起Microsoft 已经发布代码弃用变更,也就是说2016年1月1号后用SHA ...

  10. 【04】AngularJS 表达式

    AngularJS 表达式 AngularJS 使用 表达式 把数据绑定到 HTML. AngularJS 表达式 AngularJS 表达式写在双大括号内:{{ expression }}. Ang ...