problem1 link

将限制按照$x$排序。那么$[upTo_{i}+1,upTo_{i+1}]$中数字个数为$quantity_{i+1}-quantity_{i}$。然后进行动态规划。$f[i][j]$表示考虑了前$i$个区间的限制,其中偶数的个数为$j$时是否成立。

problem2 link

按照如下的规则构造这个图:首先$[1,n]$区间每个节点是单独的一个分量,每次将该区间分为两半。这两半分别需要$k-1$次。最后将这两部分连在一起。

problem3 link

如果出现这样一种情况,就是需要若干种字母去匹配另外若干种字母时,它们一定是多对一或者一对多,而不会出现多对多的情况。

假设字母$a,b,c,d$分别有$3,5,7,1$个。如果$a,b$去匹配$c,d$,不如先让$a,b$匹配一对,$c,d$匹配一对,然后2个$a$,4个$b$去匹配6个$c$。

所以如果前面出现大于一种字母有剩余的话,可以记录最后抵消它们的是哪一种字母即可。

动态规划的方程为$f[i][j][k][t]$表示到第$i$个为止,还剩下$j$个需要与后面的进行配对,其中前面剩余的未参与配对的为$t$个,$k$指示了前面剩余的$j$个是一种还是多种。

code for problem1

#include <algorithm>
#include <string>
#include <vector> class BearFair {
public:
std::string isFair(int n, int b, const std::vector<int> &upTo,
const std::vector<int> &quantity) {
int m = static_cast<int>(upTo.size());
std::vector<std::pair<int, int>> V(m);
for (int i = 0; i < m; ++i) {
V[i] = {upTo[i], quantity[i]};
}
std::sort(V.begin(), V.end());
if (V.back().second > n) {
return "unfair";
} struct node {
int ll, rr, cnt; node() = default;
node(int ll, int rr, int cnt) : ll(ll), rr(rr), cnt(cnt) {}
};
std::vector<node> all; for (int i = 0; i < m; ++i) {
if (0 == i) {
if (V[i].second > V[i].first) {
return "unfair";
}
all.emplace_back(1, V[i].first, V[i].second);
} else {
if (V[i].second < V[i - 1].second ||
(V[i].second - V[i - 1].second > V[i].first - V[i - 1].first) ||
(V[i].second != V[i - 1].second && V[i].first == V[i - 1].first)) {
return "unfair";
}
if (V[i].first != V[i - 1].first) {
all.emplace_back(V[i - 1].first + 1, V[i].first,
V[i].second - V[i - 1].second);
}
}
} if (V.back().first < b) {
all.emplace_back(V.back().first + 1, b, n - V.back().second);
} else if (V.back().second != n) {
return "unfair";
}
if (all.empty()) {
return "fair";
} int M = static_cast<int>(all.size());
std::vector<std::vector<bool>> f(M, std::vector<bool>(n + 1));
for (int i = 0; i <= all[0].cnt && i <= all[0].rr / 2; ++i) {
if (all[0].cnt - i <= all[0].rr - all[0].rr / 2) {
f[0][i] = true;
}
}
for (int i = 1; i < M; ++i) {
int even = all[i].rr / 2 - (all[i].ll - 1) / 2;
int odd = all[i].rr - all[i].ll + 1 - even;
for (int j = 0; j <= n; ++j)
if (f[i - 1][j]) {
for (int k = 0; k <= all[i].cnt && j + k <= n && k <= even; ++k) {
if (all[i].cnt - k <= odd) {
f[i][j + k] = 1;
}
}
}
}
if (f[M - 1][n / 2]) {
return "fair";
}
return "unfair";
}
};

code for problem2

#include <unordered_set>
#include <vector> class BearSpans {
public:
std::vector<int> findAnyGraph(int n, int m, int k) {
this->n = n;
this->m = m;
for (int i = 0; i < n; ++i) {
for (int j = i + 1; j < n; ++j) {
all_edges.insert(i * n + j);
}
}
if (!Dfs(0, n - 1, k)) {
return {-1};
}
while (index < m) {
auto p = *all_edges.begin();
Add(p / n, p % n);
all_edges.erase(p);
++index;
}
return result;
} private:
bool Dfs(int L, int R, int k) {
if (k == 1) {
for (int i = L + 1; i <= R; ++i) {
Add(L, i);
++index;
}
return true;
} if (L + 1 == R) {
if (k != 1) {
return false;
}
Add(L, R);
++index;
return true;
}
if (R - L + 1 == 3) {
return false;
}
int M = (L + R) >> 1;
if (!Dfs(L, M, k - 1) || !Dfs(M + 1, R, k - 1)) {
return false;
}
Add(L, R);
++index;
return true;
} void Add(int u, int v) {
result.push_back(u + 1);
result.push_back(v + 1);
all_edges.erase(u * n + v);
}
int n;
int m;
std::unordered_set<int> all_edges;
std::vector<int> result;
int index = 0;
};

code for problem3

#include <limits>
#include <string>
#include <vector> constexpr int kMaxN = 2500;
constexpr int kMaxType = 6;
constexpr int kInfinite = std::numeric_limits<int>::max(); int f[2][kMaxN][kMaxType * 2][kMaxType + 1]; class BearPairs {
public:
int minCost(const std::string &s, const std::vector<int> &cost, int m) {
int n = static_cast<int>(s.size());
auto Clear = [&](int t) {
for (int i = 0; i < n; ++i) {
for (int j = 0; j < kMaxType * 2; ++j) {
for (int k = 0; k <= m; ++k) {
f[t][i][j][k] = kInfinite;
}
}
}
};
auto Update = [&](int &x, int y) {
if (x > y) {
x = y;
}
};
Clear(0);
f[0][0][0][1] = 0;
f[0][1][s[0] - 'a'][0] = cost[0];
int pre = 0;
int cur = 1;
for (int i = 1; i < n; ++i) {
Clear(cur);
for (int j = 0; j <= i; ++j) {
for (int k = 0; k < kMaxType * 2; ++k) {
for (int t = 0; t <= m; ++t) {
int c0 = f[pre][j][k][t];
if (c0 == kInfinite) {
continue;
}
int c1 = c0 + cost[i] + 100 * i;
int c2 = c0 + cost[i] - 100 * i;
int v = s[i] - 'a';
if (t < m) {
Update(f[cur][j][k][t + 1], c0);
}
if (j == 0) {
Update(f[cur][1][v][t], c2);
} else if (k < kMaxType) {
if (v == k) {
Update(f[cur][j + 1][v][t], c2);
} else {
Update(f[cur][j - 1][k][t], c1);
for (int other = 0; other < kMaxType; ++other) {
if (other != v && other != k) {
Update(f[cur][j + 1][kMaxType + other][t], c2);
}
}
}
} else {
if (v + kMaxType == k) {
Update(f[cur][j - 1][k][t], c1);
} else {
Update(f[cur][j + 1][k][t], c2);
}
}
}
}
}
pre ^= 1;
cur ^= 1;
}
int result = kInfinite;
for (int k = 0; k < kMaxType * 2; ++k) {
result = std::min(result, f[pre][0][k][m]);
}
if (result == kInfinite) {
return -1;
}
return result;
}
};

topcoder srm 680 div1的更多相关文章

  1. Topcoder SRM 643 Div1 250<peter_pan>

    Topcoder SRM 643 Div1 250 Problem 给一个整数N,再给一个vector<long long>v; N可以表示成若干个素数的乘积,N=p0*p1*p2*... ...

  2. Topcoder Srm 726 Div1 Hard

    Topcoder Srm 726 Div1 Hard 解题思路: 问题可以看做一个二分图,左边一个点向右边一段区间连边,匹配了左边一个点就能获得对应的权值,最大化所得到的权值的和. 然后可以证明一个结 ...

  3. topcoder srm 714 div1

    problem1 link 倒着想.每次添加一个右括号再添加一个左括号,直到还原.那么每次的右括号的选择范围为当前左括号后面的右括号减去后面已经使用的右括号. problem2 link 令$h(x) ...

  4. topcoder srm 738 div1 FindThePerfectTriangle(枚举)

    Problem Statement      You are given the ints perimeter and area. Your task is to find a triangle wi ...

  5. Topcoder SRM 602 div1题解

    打卡- Easy(250pts): 题目大意:rating2200及以上和2200以下的颜色是不一样的(我就是属于那个颜色比较菜的),有个人初始rating为X,然后每一场比赛他的rating如果增加 ...

  6. Topcoder SRM 627 div1 HappyLettersDiv1 : 字符串

    Problem Statement      The Happy Letter game is played as follows: At the beginning, several players ...

  7. Topcoder SRM 584 DIV1 600

    思路太繁琐了 ,实在不想解释了 代码: #include<iostream> #include<cstdio> #include<string> #include& ...

  8. TopCoder SRM 605 DIV1

    604的题解还没有写出来呢.先上605的. 代码去practice房间找. 说思路. A: 贪心,对于每个类型的正值求和,如果没有正值就取最大值,按着求出的值排序,枚举选多少个类型. B: 很明显是d ...

  9. topcoder srm 575 div1

    problem1 link 如果$k$是先手必胜那么$f(k)=1$否则$f(k)=0$ 通过对前面小的数字的计算可以发现:(1)$f(2k+1)=0$,(2)$f(2^{2k+1})=0$,(3)其 ...

随机推荐

  1. sqli-labs(四)

    第七关: 输入?id=1 页面显示如下,可以看出这关大概是锻炼利用sql来写入一句话木马. 这里说我下我的探测流程(主要是为了知道后台的sql是怎样拼凑的): 输入?id=1' 报错  说明后台是用的 ...

  2. 工厂模式&策略模式。

    抽象.封装,具体事情做得越多,越容易犯错误.这每个做过具体工作的人都深有体会,相反,官做得越高,说出的话越抽象越笼统,犯错误可能性就越少.好象我们从编程序中也能悟出人生道理.(百度百科) 不断抽象封装 ...

  3. LeetCode83.删除排序链表中的重复的元素

    给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次. 示例 1: 输入: 1->1->2 输出: 1->2 示例 2: 输入: 1->1->2->3-&g ...

  4. Android -- 自定义ViewGroup实现FlowLayout效果

    1,在开发的时候,常在我们的需求中会有这种效果,添加一个商品的一些热门标签,效果图如下: 2,从上面效果可以看得出来,这是一个自定义的ViewGroup,然后实现换行效果,让我们一起来实现一下 自定义 ...

  5. Java多线程-----原子变量和CAS算法

       原子变量      原子变量保证了该变量的所有操作都是原子的,不会因为多线程的同时访问而导致脏数据的读取问题      Java给我们提供了以下几种原子类型: AtomicInteger和Ato ...

  6. arc 092D Two Sequences

    题意: 给出两个长度N相同的整数序列A和B,有N^2种方式从A中选择一个数Ai,从B中选择一个数Bj,让两个数相加,求这N^2个数的XOR,即异或. 思路: 暴力的求显然是会超时的,因为是异或,就考虑 ...

  7. Java基础语法(一 )

    一.关键字 关键字概述 被Java语言赋予特定含义的单词 关键字特点 组成关键字的字母全部小写 关键字注意事项 goto和const作为保留字存在,目前并不使用 关键字单词 用于定义数据类型的关键字 ...

  8. orb slam2 双目摄像头

    主要参考了http://blog.csdn.net/awww797877/article/details/51171099这篇文章,其中需要添加的是:export ROS_PACKAGE_PATH=$ ...

  9. 人工智能深度学习框架MXNet实战:深度神经网络的交通标志识别训练

    人工智能深度学习框架MXNet实战:深度神经网络的交通标志识别训练 MXNet 是一个轻量级.可移植.灵活的分布式深度学习框架,2017 年 1 月 23 日,该项目进入 Apache 基金会,成为 ...

  10. flask框架----数据库连接池

    数据库连接池 flask中是没有ORM的,如果在flask里面连接数据库有两种方式 一:pymysql 二:SQLAlchemy 是python 操作数据库的一个库.能够进行 orm 映射官方文档 s ...