problem1 link

最优选择一定是在$2n$个端点中选出两个。

problem2 link

分开考虑每个区间。设所有区间的左端点的最大值为$lc$,所有区间的右端点的最小值为$rc$.对于某个区间$L$,其实就是找最少的区间(包括$L$)能够完全覆盖区间$[lc,rc]$.

设$L$的左右端点为$L_{1},L_{2}$。考虑从$L_{1}$向左扩展,每次扩展一定是找一个区间$p$满足$p_{2}\geq L_{1}$且使得$p_{1}$最小。右端点向右扩展类似。

problem3 link

对于后手来说,它一定是每次只放置一个障碍格子在先手目前的位置。否则,如果放置了太多,那么先手就容易决策出向左还是向右比较好。

对于先手来说,假设目前先手在$(r,c)$,那么如果$(r,c)$和$(r+1,c)$之间没有障碍,且轮到先手,应该直接跳到$(r+1,c)$,否则,那么由后手的策略来看,此时已经有的障碍一定是一个包含$(r,c)$的区间,此时先手可以尝试向左或者向右运动到障碍区间外一个格子。

这样就可以用$(r,c,left,right,tag)$来表示一个状态来进行动态规划。$(r,c)$表示先手目前的位置,$(left, right)$表示目前障碍的区间,$tag$指示目前是先手还是后手。

code for problem1

#include <vector>

class EelAndRabbit {
public:
int getmax(std::vector<int> &l, std::vector<int> t) {
const int n = static_cast<int>(l.size());
int ans = 0;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < 2; ++j) {
int p1 = j == 0 ? -t[i] : -t[i] - l[i];
for (int k = 0; k < n; ++k) {
for (int r = 0; r < 2; ++r) {
int p2 = r == 0 ? -t[k] : -t[k] - l[k];
if (p1 != p2) {
int num = 0;
long long mask = 0;
for (int x = 0; x < n; ++x) {
if ((-t[x] - l[x] <= p1 && p1 <= -t[x]) ||
(-t[x] - l[x] <= p2 && p2 <= -t[x])) {
if ((mask & (1ll << x)) == 0) {
++num;
mask |= 1ll << x;
}
}
}
ans = std::max(ans, num);
}
}
}
}
}
return ans;
}
};

code for problem2

#include <algorithm>
#include <string>
#include <vector> constexpr int N = 2500;
constexpr int M = 10000; int s[N], t[N];
int back[M], next[M];
int back_cost[M], next_cost[M];
int sort_idx[N]; class ShoutterDiv1 {
public:
int count(const std::vector<std::string>& s1000,
const std::vector<std::string>& s100,
const std::vector<std::string>& s10,
const std::vector<std::string>& s1,
const std::vector<std::string>& t1000,
const std::vector<std::string>& t100,
const std::vector<std::string>& t10,
const std::vector<std::string>& t1) {
int n = 0;
for (const auto& e : s1000) {
n += static_cast<int>(e.size());
}
for (int i = 0; i < n; ++i) {
s[i] = t[i] = 0;
sort_idx[i] = i;
}
for (int i = 0; i < M; ++i) {
back[i] = next[i] = i;
}
Parse(s1000, s, 1000);
Parse(s100, s, 100);
Parse(s10, s, 10);
Parse(s1, s, 1);
Parse(t1000, t, 1000);
Parse(t100, t, 100);
Parse(t10, t, 10);
Parse(t1, t, 1); int c_left = t[0];
int c_right = s[0];
for (int i = 0; i < n; ++i) {
back[t[i]] = std::min(back[t[i]], s[i]);
next[s[i]] = std::max(next[s[i]], t[i]);
c_left = std::min(c_left, t[i]);
c_right = std::max(c_right, s[i]);
}
for (int i = M - 2; i >= 0; --i) {
back[i] = std::min(back[i], back[i + 1]);
}
for (int i = 1; i < M; ++i) {
next[i] = std::max(next[i], next[i - 1]);
}
for (int i = 0; i < M; ++i) {
if (i <= c_left) {
back_cost[i] = 0;
} else if (i == back[i]) {
back_cost[i] = -1;
} else {
if (back_cost[back[i]] == -1) {
back_cost[i] = -1;
} else {
back_cost[i] = 1 + back_cost[back[i]];
}
}
}
for (int i = M - 1; i >= 0; --i) {
if (i >= c_right) {
next_cost[i] = 0;
} else if (i == next[i]) {
next_cost[i] = -1;
} else {
if (next_cost[next[i]] == -1) {
next_cost[i] = -1;
} else {
next_cost[i] = 1 + next_cost[next[i]];
}
}
}
auto Cost = [&](int left, int right) {
if (back_cost[left] == -1 || next_cost[right] == -1) {
return -1;
}
return back_cost[left] + next_cost[right];
}; std::sort(sort_idx, sort_idx + n, [&](int x, int y) {
return s[x] < s[y] || (s[x] == s[y] && t[x] < t[y]);
}); int result = 0;
for (int i = 0; i < n; ++i) {
int tmp = Cost(s[sort_idx[i]], t[sort_idx[i]]);
for (int j = 0; j < N && s[sort_idx[j]] <= s[sort_idx[i]]; ++j) {
if (t[sort_idx[i]] <= t[sort_idx[j]]) {
int val = Cost(s[sort_idx[j]], t[sort_idx[j]]);
if (val != -1 && (tmp == -1 || tmp > 1 + val)) {
tmp = 1 + val;
}
}
}
if (tmp == -1) {
return -1;
}
result += tmp;
}
return result;
} private:
void Parse(const std::vector<std::string>& d, int* data, int base) {
int idx = 0;
for (size_t i = 0; i < d.size(); ++i) {
for (size_t j = 0; j < d[i].size(); ++j) {
data[idx++] += (d[i][j] - '0') * base;
}
}
}
};

code for problem3

#include <cstring>
#include <limits>
#include <string>
#include <vector> #include <iostream> constexpr int N = 50;
constexpr int kEachUseBit = 16;
constexpr int kRabbitTagBit = 31;
constexpr int kEelTagBit = 15;
constexpr int kMask = (1 << (kEachUseBit - 1)) - 1; using TType = unsigned int; TType rabbit_eel[N][N][N][N + 1];
int cost[N][N];
int h, w; class WallGameDiv1 {
public:
int play(const std::vector<std::string> &costs) {
h = static_cast<int>(costs.size());
w = static_cast<int>(costs[0].size());
for (int i = 0; i < h; ++i) {
cost[i][0] = costs[i][0] - '0';
for (int j = 1; j < w; ++j) {
cost[i][j] = cost[i][j - 1] + costs[i][j] - '0';
}
} memset(rabbit_eel, 0, sizeof(rabbit_eel));
// Iterator each row to avoid more depths of recursion.
for (int i = h - 1; i >= 0; --i) {
for (int j = 0; j < w; ++j) {
Eel(i, j, j, j);
}
}
int result = std::numeric_limits<int>::max();
for (int i = 0; i < w; ++i) {
result = std::min(result, Cost(0, i, i) + Eel(0, i, i, i));
}
return result;
} private:
bool Computed(const TType &val, bool is_rabbit) {
if (is_rabbit) {
return (val & (1u << kRabbitTagBit)) != 0;
} else {
return (val & (1u << kEelTagBit)) != 0;
}
} int GetCost(const TType &val, bool is_rabbit) {
if (!Computed(val, is_rabbit)) {
return -1;
}
if (is_rabbit) {
return static_cast<int>((val >> kEachUseBit) & kMask);
} else {
return static_cast<int>(val & kMask);
}
} int SetCost(TType &val, bool is_rabbit, int cost) {
if (is_rabbit) {
val |= (static_cast<TType>(cost)) << kEachUseBit;
val |= 1u << kRabbitTagBit;
} else {
val |= cost;
val |= 1u << kEelTagBit;
}
return cost;
} int Eel(int row, int col, int left, int right) {
TType &val = rabbit_eel[row][col][left][right];
int result = GetCost(val, false);
if (result != -1) {
return result;
}
if (row == h - 1) {
return SetCost(val, false, 0);
}
result = Rabbit(row, col, left, right); if (right - left < w - 1) {
result = std::max(result, Rabbit(row, col, std::min(col, left),
std::max(col + 1, right)));
} return SetCost(val, false, result);
} int Rabbit(int row, int col, int left, int right) {
TType &val = rabbit_eel[row][col][left][right];
int result = GetCost(val, true);
if (result != -1) {
return result;
}
if ((left <= col) && (col < right)) {
result = std::numeric_limits<int>::max();
if (left > 0) {
result = Cost(row, left - 1, col - 1) + Eel(row, left - 1, left, right);
}
if (right < w) {
result = std::min(
result, Cost(row, col + 1, right) + Eel(row, right, left, right));
}
} else {
result = Cost(row + 1, col, col) + Eel(row + 1, col, col, col);
}
return SetCost(val, true, result);
} int Cost(int row, int left, int right) {
if (left <= right) {
if (left == 0) {
return cost[row][right];
}
return cost[row][right] - cost[row][left - 1];
}
return 0;
}
};

topcoder srm 580 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. thymeleaf(二)

    项目demo     http://pan.baidu.com/s/1wg6PC 学习资料网址  http://www.blogjava.net/bjwulin/archive/2013/02/07/ ...

  2. 【Java线程安全】 — 常用数据结构及原理(未完结)

    本文主要记录自己对于多线程安全的学习,先来记几个线程安全模型. 首先最重要的当然是volatile和AQS了: 我们知道,整个java.cuncurrent包的核心就是volatile,CAS加自旋悲 ...

  3. Spring-Boot 内置静态资源文件地址修改

    Spring-Boot 内置MVC静态文件地址修改 Why:1.Spring-Boot修改内置SpringMVC静态资源路径,提高项目目录结构的安全性.2.配置拦截路径时可以剔除静态文件拦截How:1 ...

  4. jquery 在页面上根据ID定位(jQuery锚点跳转及相关操作) 经典

    1.锚点跳转简介 Edit 锚点其实就是可以让页面定位到某个位置上的点.在高度较高的页面中经常见到.比如百度的百科页面,wiki中的page内容. 我知道实现锚点的跳转有两种形式,一种是a标签+nam ...

  5. Dubbo 分布式服务框架入门

    要想了解 Dubbo 是什么,我们不防先了解它有什么用.使用场景:比如我想开发一个网上商城项目,这个网上商城呢,比较复杂,分为 pc 端 web 管理后台,微信端销售公众号,那么我们分成四个项目,pc ...

  6. linux ---部署django项目篇

    uWSGI + nginx+ django + virtualenv + supervisor发布web服务器 项目部署步骤 1.项目准备阶段 1.准备项目代码,从本地拷贝 2.将项目上传到linux ...

  7. 关闭shift中英文切换 英文代码/中文注释随意切换着写。

    x 背景 写代码的时候总是意外的就切成中文了,特别是代码中大小写切换的这种情况... 例如:"public static TimeZone CurrentTime..."publi ...

  8. 算法基础_递归_给定一个数字n,打印出所有的划分等式

    问题描述: 给定一个数字n,打印出所有的划分等式 例: n = 3 3 2+1 1+1+1 解题源代码: import java.util.Scanner; /** * 给定数字n,打印出其所有用加法 ...

  9. [No0000197]Windows用户都应该知道的运行命令

    通过"运行"命令,运行Windows丰富工具的方法.如果您知道工具或任务的相应"运行"命令,那么您就知道访问所述工具或任务的最快方法. 以下是我们最喜欢的Run ...

  10. 只需十四步:从零开始掌握 Python 机器学习(附资源)

    分享一篇来自机器之心的文章.关于机器学习的起步,讲的还是很清楚的.原文链接在:只需十四步:从零开始掌握Python机器学习(附资源) Python 可以说是现在最流行的机器学习语言,而且你也能在网上找 ...