[Codeforces778E]Selling Numbers
Problem
给一个由问号和数字组成的数字串A(问号表示任一数字)。
再给定n个数字Bi,和0~9的数字的价值。
F(x)表示x各个位数上的价值和。问A为何值时,sum(F(Bi+A))的值最大为多少。
1 ≤ A,Bi < 101000 没有前导零
Solution
dp[i][j]表示第i位时有j个数发生进位时的最大值。
然后我们对有没有进位的情况进行分类讨论
Notice
每次做之前要radixsort一下
Code
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define rank t
#define sqz main
#define ll long long
#define reg register int
#define rep(i, a, b) for (reg i = a; i <= b; i++)
#define per(i, a, b) for (reg i = a; i >= b; i--)
#define travel(i, u) for (reg i = head[u]; i; i = edge[i].next)
const int INF = 1e9, N = 1000;
const double eps = 1e-6, phi = acos(-1);
ll mod(ll a, ll b) {if (a >= b || a < 0) a %= b; if (a < 0) a += b; return a;}
ll read(){ ll x = 0; int zf = 1; char ch; while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
if (ch == '-') zf = -1, ch = getchar(); while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar(); return x * zf;}
void write(ll y) { if (y < 0) putchar('-'), y = -y; if (y > 9) write(y / 10); putchar(y % 10 + '0');}
int rank[N + 5], S[N + 5][N + 5], now[N + 5], num[10], F[N + 5][N + 5], len[N + 5], V[10];
char st[N + 5][N + 5];
int m;
void radixsort(int pos)
{
memset(num, 0, sizeof num);
rep(i, 1, m) num[S[i][pos]]++;
per(i, 9, 1) num[i - 1] += num[i];
per(i, m, 1) now[num[S[rank[i]][pos]]--] = rank[i];
rep(i, 1, m) rank[i] = now[i];
}
int sqz()
{
scanf("%s", st[0] + 1);
int n = len[0] = strlen(st[0] + 1);
m = read();
rep(i, 1, m) scanf("%s", st[i] + 1), len[i] = strlen(st[i] + 1), n = max(n, len[i]);
n++;
rep(i, 0, m)
rep(j, 1, len[i])
S[i][j + n - len[i]] = (st[i][j] == '?' ? -1 : st[i][j] - '0');
rep(i, 0, 9) V[i] = read();
rep(i, 1, n)
rep(j, 0, m) F[i][j] = -INF;
int l = S[0][n] == -1 ? 0 : S[0][n], r = S[0][n] == -1 ? 9 : S[0][n];
rep(i, l, r)
{
int cnt = 0, total = 0;
rep(j, 1, m)
{
if (i + S[j][n] >= 10) cnt++;
total += V[(i + S[j][n]) % 10];
}
F[n][cnt] = max(F[n][cnt], total);
}
rep(i, 1, m) rank[i] = i;
rank[m + 1] = m + 1;
per(i, n - 1, 1)
{
radixsort(i + 1);
int l = S[0][i] == -1 ? 0 : S[0][i], r = S[0][i] == -1 ? 9 : S[0][i];
if (n - i + 1 == len[0] && l == 0) l++;
rep(num, l, r)
{
int cnt = 0, total = 0;
rep(j, 1, m)
{
if (max(len[j], len[0]) < n - i + 1) continue;
total += V[(S[j][i] + num) % 10];
cnt += S[j][i] + num >= 10;
}
rep(j, 1, m + 1)
{
F[i][cnt] = max(F[i][cnt], F[i + 1][j - 1] + total);
total += (max(len[rank[j]], len[0]) >= n - i + 1 || (S[rank[j]][i] + num + 1) ? V[(S[rank[j]][i] + num + 1) % 10] : 0) - (max(len[rank[j]], len[0]) >= n - i + 1 || (S[rank[j]][i] + num)? V[(S[rank[j]][i] + num) % 10] : 0);
cnt += S[rank[j]][i] + num + 1 == 10;
}
}
}
int ans = 0;
rep(i, 0, m) ans = max(ans, F[1][i]);
printf("%d\n", ans);
return 0;
}
[Codeforces778E]Selling Numbers的更多相关文章
- Codeforces Round #402 (Div. 1)
A题卡壳了,往离线倒着加那方面想了会儿,后来才发现方向错了,二十多分钟才过掉,过了B后做D,想法好像有点问题,最后只过两题,掉分了,差一点回紫. AC:AB Rank:173 Rating:2227- ...
- Codeforces Round#402(Div.1)掉分记+题解
哎,今天第一次打div1 感觉头脑很不清醒... 看到第一题就蒙了,想了好久,怎么乱dp,倒过来插之类的...突然发现不就是一道sb二分吗.....sb二分看了二十分钟........ 然后第二题看了 ...
- Java 位运算2-LeetCode 201 Bitwise AND of Numbers Range
在Java位运算总结-leetcode题目博文中总结了Java提供的按位运算操作符,今天又碰到LeetCode中一道按位操作的题目 Given a range [m, n] where 0 <= ...
- POJ 2739. Sum of Consecutive Prime Numbers
Sum of Consecutive Prime Numbers Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 20050 ...
- [LeetCode] Add Two Numbers II 两个数字相加之二
You are given two linked lists representing two non-negative numbers. The most significant digit com ...
- [LeetCode] Maximum XOR of Two Numbers in an Array 数组中异或值最大的两个数字
Given a non-empty array of numbers, a0, a1, a2, … , an-1, where 0 ≤ ai < 231. Find the maximum re ...
- [LeetCode] Count Numbers with Unique Digits 计算各位不相同的数字个数
Given a non-negative integer n, count all numbers with unique digits, x, where 0 ≤ x < 10n. Examp ...
- [LeetCode] Bitwise AND of Numbers Range 数字范围位相与
Given a range [m, n] where 0 <= m <= n <= 2147483647, return the bitwise AND of all numbers ...
- [LeetCode] Valid Phone Numbers 验证电话号码
Given a text file file.txt that contains list of phone numbers (one per line), write a one liner bas ...
随机推荐
- st2_057
http://vulapps.evalbug.com/s_struts2_s2-057/ 这大概是全网复现st2-057环境最简单的操作了. 不过首先,你需要安装过docker,安装方法参考官方文档h ...
- bootstrapTable 合并单元格
/** * 合并单元格 * @param data 原始数据(在服务端完成排序) * @param fieldName 合并属性名称 * @param colspan 合并列 * @param tar ...
- 关于angular2 打包(一)
在讲到angular2 及以上项目打包之前,我先讲一下.angular cli 拥有自己的打包工具,熟悉的可以直接上手.如果用不惯,也可以去使用webpack 之类的.内置的systemjs也是很好用 ...
- P2365 任务安排 / [FJOI2019]batch(斜率优化dp)
P2365 任务安排 batch:$n<=10000$ 斜率优化入门题 $n^{3}$的dp轻松写出 但是枚举这个分成多少段很不方便 我们利用费用提前的思想,提前把这个烦人的$S$在后面的贡献先 ...
- Docker Kubernetes 健康检查
Docker Kubernetes 健康检查 提供Probe探测机制,有以下两种类型: livenessProbe:如果检查失败,将杀死容器,然后根据Pod的重启策略来决定是否重启. readines ...
- python 排序算法
冒泡排序: 一. 冒泡排序的定义 冒泡排序(英语:Bubble Sort)是一种简单的排序算法.它重复地遍历要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.遍历数列的工作是重复地进 ...
- 剑指offer(34)第一个只出现一次的字符
题目描述 在一个字符串(1<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置 题目分析 只需要用map记录字符出现的次数就行,比较简单的题 代码 f ...
- 【BZOJ1485】有趣的数列
Description 我们称一个长度为2n的数列是有趣的,当且仅当该数列满足以下三个条件: (1)它是从1到2n共2n个整数的一个排列{ai}: (2)所有的奇数项满足a1<a3<…&l ...
- CF438E The Child and Binary Tree
思路 设F(x)的第x项系数为权值和为x的答案 题目中要求权值必须在集合中出现,这个不好处理,考虑再设一个C,C的第x项如果是1代表x出现在值域里,如果是0,代表x没有出现在值域里,然后由于二叉树可以 ...
- 论文阅读:Deep Attentive Tracking via Reciprocative Learning
Deep Attentive Tracking via Reciprocative Learning 2018-11-14 13:30:36 Paper: https://arxiv.org/abs/ ...