题目大意:

你有$k$个数,分为$26$种

对于每个数,你可以选择选进$A$集合或者$B$集合或者不选

要求$A$集合中必须有$n$个数,$B$集合中必须有$m$个数

记第$i$种数在$A$集合中的个数为$a_i$,$B$中个数为$b_i$

试最小代价$\sum a_i * b_i$

$k \leqslant 200000$,$n, m \leqslant 30000$

首先,我们打表得出一个结论,代价一定只由一种数得出

考虑证明:

我们不妨设代价由$A$得出,且集合$S_A$和$S_B$中分别有$i$个$A$和$a - i$个$A$

那么,如果我们尝试用$B$来替换$A$,不妨设从$B$中抽了$j$个$B$扔进$A$中,且一共有$b$个$B$

那么贡献差为$i * (a - i) - ((i - j) * (a - i + j) + j * (b - j))(0 \leq j \leq min(i, b))$

化简后,为$2j^2 - j(2i - a+ b)$

这是一个开口向上的,以$j$为自变量的二次函数

最大值一定在端点取到,也就是$j = 0$或者$j = i$或者$j = b$取到

这三种情况对应着代价由$A$得出或者由$B$得出

我们可以枚举在中间的种类是哪一个

之后再枚举放在$A$中的数能取多少个

相应地我们可以知道最多可以放在$B$中多少个

可以通过背包来实现上述问题

由于实现不优,复杂度为$O(26^2 * (n+ m) + 26 * k)$

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
namespace remoon {
#define ri register int
#define tpr template <typename ra>
#define rep(iu, st, ed) for(ri iu = st; iu <= ed; iu ++)
#define drep(iu, ed, st) for(ri iu = ed; iu >= st; iu --)
#define gc getchar
inline int read() {
int p = , w = ; char c = gc();
while(c > '' || c < '') { if(c == '-') w = -; c = gc(); }
while(c >= '' && c <= '') p = p * + c - '', c = gc();
return p * w;
}
int wr[], rw;
#define pc(iw) putchar(iw)
tpr inline void write(ra o, char c = '\n') {
if(!o) pc('');
if(o < ) o = -o, pc('-');
while(o) wr[++ rw] = o % , o /= ;
while(rw) pc(wr[rw --] + '');
pc(c);
}
}
using namespace std;
using namespace remoon;
#define sid 30050
#define kid 200050 char s[kid];
bool f[kid];
int n, m, k, t, cnt[]; inline int judge() {
f[] = ;
memset(f, , sizeof(f));
rep(i, , ) drep(j, k, cnt[i])
f[j] |= f[j - cnt[i]];
rep(i, n, k - m)
if(f[i]) { puts(""); return ; }
return ;
} inline void solve() {
int ans = 1e9;
rep(i, , ) {
memset(f, , (n + m) << );
f[] = ;
rep(j, , ) if(i != j)
drep(v, n + m, cnt[j]) f[v] |= f[v - cnt[j]]; rep(j, , n + m)
if(f[j]) {
int l = max(n - j, );
int r = max(m - (k - cnt[i] - j), );
if(l + r <= cnt[i]) ans = min(ans, l * r);
}
}
write(ans);
} int main() {
t = read();
while(t --) {
n = read(); m = read(); k = read();
scanf("%s", s + );
int sn = strlen(s + );
memset(cnt, , sizeof(cnt));
rep(i, , sn) ++ cnt[s[i] - 'A'];
if(judge()) continue;
solve();
}
return ;
}

CodeForces 1070J Streets and Avenues in Berhattan 性质+动态规划的更多相关文章

  1. Codeforces 1070J Streets and Avenues in Berhattan dp

    Streets and Avenues in Berhattan 我们首先能发现在最优情况下最多只有一种颜色会分别在行和列, 因为你把式子写出来是个二次函数, 在两端取极值. 然后我们就枚举哪个颜色会 ...

  2. CF 1070J Streets and Avenues in Berhattan

    DP的数组f其实开得不够大,应该开200000,但是它在cf上就是过了... 题意是把一堆字母分别分配到行和列. 分析一下,答案实际上只和n行中和m列中每种字母分配的个数有关.而且答案只和" ...

  3. 2018-2019 ICPC, NEERC J. Streets and Avenues in Berhattan(DP)

    题目链接:https://codeforc.es/contest/1070/problem/J 题意:给出一个长度为 k 的字符串,选出 n 个和 m 个不同位置的字符构成两个字符串,使得两个字符串相 ...

  4. codeforces 447E or 446C 线段树 + fib性质或二次剩余性质

    CF446C题意: 给你一个数列\(a_i\),有两种操作:区间求和:\(\sum_{i=l}^{r}(a[i]+=fib[i-l+1])\).\(fib\)是斐波那契数列. 思路 (一) codef ...

  5. Codeforces 1383C - String Transformation 2(找性质+状压 dp)

    Codeforces 题面传送门 & 洛谷题面传送门 神奇的强迫症效应,一场只要 AC 了 A.B.D.E.F,就一定会把 C 补掉( 感觉这个 C 难度比 D 难度高啊-- 首先考虑对问题进 ...

  6. Codeforces 1067E - Random Forest Rank(找性质+树形 dp)

    Codeforces 题面传送门 & 洛谷题面传送门 一道不知道能不能算上自己 AC 的 D1E(?) 挺有意思的结论题,结论倒是自己猜出来了,可根本不会证( 开始搬运题解 ing: 碰到这样 ...

  7. Codeforces 809C - Find a car(找性质)

    Codeforces 题目传送门 & 洛谷题目传送门 首先拿到这类题第一步肯定要分析题目给出的矩阵有什么性质.稍微打个表即可发现题目要求的矩形是一个分形.形式化地说,该矩形可以通过以下方式生成 ...

  8. Codeforces Round #382 (Div. 2)C. Tennis Championship 动态规划

    C. Tennis Championship 题目链接 http://codeforces.com/contest/735/problem/C 题面 Famous Brazil city Rio de ...

  9. Codeforces 822D My pretty girl Noora - 线性筛 - 动态规划

    In Pavlopolis University where Noora studies it was decided to hold beauty contest "Miss Pavlop ...

随机推荐

  1. PHP autoload自动加载机制

    原文地址: http://www.jb51.net/article/31399.htm 一直不是很明白__autoload()和spl_autoload_register()到底有什么不同,找到了一个 ...

  2. 无需登录-悟空CRM 存储型XSS

    无需登录-悟空CRM 存储型XSS 审计悟空的缘由是看见某云爆出CRM的getshell,于是就想着去挖出来瞅瞅!但可能自己把自己给局限了,就想着去挖那些无限制访问的文件. 故事的发生点 漏洞文件:/ ...

  3. 2016.5.21——Compare Version Numbers

    Compare Version Numbers 本题收获: 1.字符串型数字转化为整型数字的方法:s[i] - '0',( 将字母转化为数字是[i]-'A'   ) 2.srt.at(),substr ...

  4. Dream------scala--Tuple、Array、Map与文件操作

    1.Tuple(元组) 一般使用中,假设一个函数返回多个值,我们可以使用tuple接受这个(val (x,y) = myfunction) package com.wls.scala.hello /* ...

  5. 如何和统计学家分享数据How to share data with a statistician

    如何和统计学家分享数据 原文地址:https://github.com/jtleek/datasharing 将原文渣翻译的版本. 这是一份指南给需要分享数据给统计学家或者数据科学家的任何人.我认为的 ...

  6. IDL界面程序直接调用envi菜单对应功能

    参考自http://blog.sina.com.cn/s/blog_764b1e9d010115qu.html 参考文章的方法是构建一个button控件,通过单击实现,这种方法比较复杂,不是我们经常能 ...

  7. Django集成Xadmin list index out of range报错解决方案

    return self.render(context) File "C:\Python36\lib\site-packages\django\template\defaulttags.py& ...

  8. log4j与commons-logging slf4j的关系

    1. slf4j     他只提供一个核心slf4j api(就是slf4j-api.jar包),这个包只有日志的接口并没有实现     所以如果要使用就得再给它提供一个实现了些接口的日志包,     ...

  9. 【前端vue开发架构】vue开发单页项目架构总结

    为营销活动设计的前端架构 主要的技术栈为 Vuejs,Webpack,请自行阅读如下技术或者框架的文档: 一.基础说明: node (https://nodejs.org/en/) npm (http ...

  10. RStdio常用快捷键

    掌握常用快捷键的使用, 可以让我们的效率加倍! 下面只列举了一些最常见的快捷键, RStdio的快捷键远不止这些, 具体的可以参照这里. 无论是在控制台还是在编辑区, Tab都可以帮助我们对代码进行补 ...