problem1 link

设$f[i][j][k]$表示考虑了前$i$道题,剩下时间为$j$,剩下技能为$k$的最大得分.

从小到大计算二元组$(j,k)$的话,在存储上可以省略掉$i$这一维.

problem2 link

首先,不同的提交状态有8种.预计算每一种提交状态的每一个分值的种数,设为$g[mask][score]$.对于$g[mask][score]$的计算,可以枚举$mask$包含的一个题目,设为$i$,其分值为$p_{i}$,那么第$i$道题得分如果为$x$,那么其他$mask^{'}=mask$^$2^{i}$题目得分为$score-x$,所以$g[mask][score]=\sum_{x=1}^{p_{i}}g[mask^{'}][score-x]$

最后从前向后考虑每个人的得分.设$f[i][score]$表示前$i$个人的得分降序排列且第$i$个人得分为$score$的方案数.设第$i+1$个人的得分为$y$,由于第$i$个人的得分一定大于$y$,所以$f[i+1][y]=\sum_{x=y+1}^{MaxScore_{i}}f[i][x]$

由于计算数组$g$和$f$都是连续求和,可以通过预处理前缀和或者后缀和来加速计算

problem3 link

将所有人按照是否攻击别人和是否被攻击成功分为四类,即YY,YN,NY,NN.设这四类的个数分别为$A,B,C,D,A+B+C+D=n$.所有的攻击一共有$T=A+B$个.

明显如果$A+C>B+C$,那么答案为0.下面认为$C \le B$

现在就是要构造一个$T*2$的二维表,某一行的两列的两个值$r_{1},r_{2}$,表示有一条攻击是$r_{1}->r_{2}$

对于第一类中的每个元素$e$,它一定在第一列第二列同时出现过,并且可能在第二列出现过多次.现在只考虑出现在第二列且被攻击成功的那一行,设其为$y$,设出现的第一列的行为$x$,那么有$x<y$.

现在来计算把$A$个第一类元素放到这个表中的方案数.可以用动态规划来计算.设$f[T][A]$表示把$A$个元素放入到一个$T*2$表中的方案数.现在先假设所有的$A$个元素是一样的,即没有先后顺序.

考虑第一行的第一列,有两种情况:

(1)没有放置$A$中的元素,那么情况为$f[T-1][A]$

(2)放置了一个,那么这个元素出现在第二列的行数在后面的$T-1$行中,且这$T-1$行的第二列中已经放置了$A-1$个,所以还有$(T-1)-(A-1)=T-A$个位置,即答案为$(T-A)*f[T-1][A-1]$

所以$f[T][A]=f[T-1][A]+(T-A)*f[T-1][A-1]$

现在对于第二列放置的每个第一类的元素,这一行所代表的攻击是成功的.也就是说对应的第一列也已经有了攻击者(可能是第一类或者第二类的元素).$f[T][A]$已经保证了对于第一类元素的合理性.

现在现在第一列对应的$T-A=B$个元素(这些元素可能是第二类也可能是第一类但还没有攻击对手)还没有攻击的对象,因为这$B$个攻击中有$C$个需要是成功的,所以有$C_{B}^{C}$个选择.现在第一列还有$B-C$个还没有攻击对象,并且这些攻击都是失败的,所以只要不是它自己就行,所以每个有$n-1$种.

最后所有的元素都是不同的,所以要乘以它们的阶乘.所以答案为$f[A+B][A]*C_{B}^{C}*(n-1)^{B-C}*A!*B!*C!$

code for problem1

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std; class SRMCodingPhase {
public:
int countScore(vector <int> points, vector <int> skills, int luck) {
vector<vector<int>> f(76, vector<int>(luck + 1, -1));
f[75][luck] = 0;
const int b[] = {2, 4, 8};
for (int i = 0; i < 3; ++ i) {
const int point = points[i];
const int skill = skills[i];
for (int j = 0; j <= 75; ++ j) {
for (int k = 0; k <= luck; ++ k) {
if (f[j][k] == -1) {
continue;
}
for (int t = 0; t <= k && t < skill; ++ t) {
const int last_point = point - b[i] * (skill - t);
if (last_point <= 0) {
continue;
}
if (skill - t > j) {
continue;
}
f[j - (skill - t)][k - t] = max(f[j - (skill - t)][k - t], last_point + f[j][k]);
}
}
}
}
int result = 0;
for (int j = 0; j <= 75; ++ j) {
for (int k = 0; k <= luck; ++ k) {
result = max(result, f[j][k]);
}
}
return result;
}
};

  

code for problem2

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
using namespace std; #define mod 1000000007
#define MAX_SCORE 200000 int g[8][MAX_SCORE + 1];
int f[20][MAX_SCORE + 1]; class SRMIntermissionPhase {
public:
int countWays(vector<int> points, vector<string> description) {
Initialize(points); const int mask0 = GetMask(description[0]);
for (int i = 0; i <= MAX_SCORE; ++ i) {
f[0][i] = GetRangeSum(mask0, i, i);
}
CalculateSuffixSum(0);
const int person_number = (int)description.size();
for (int i = 1; i < person_number; ++ i) {
const int mask = GetMask(description[i]);
for (int j = 0; j < MAX_SCORE; ++ j) {
f[i][j] = (long long)GetRangeSum(mask, j, j) * f[i - 1][j + 1] % mod;
}
CalculateSuffixSum(i);
}
return f[person_number - 1][0];
}
private: void CalculateSuffixSum(int idx) {
for (int i = MAX_SCORE - 1; i >= 0; -- i) {
Add(f[idx][i], f[idx][i + 1]);
}
}
void CalculatePrefixSum(int idx) {
for (int i = 1; i <= MAX_SCORE; ++ i) {
Add(g[idx][i], g[idx][i - 1]);
}
} int GetMask(const std::string& s) {
int mask = 0;
for (int i = 0; i < 3; ++ i) {
if (s[i] == 'Y') {
mask |= 1 << i;
}
}
return mask;
} void Initialize(const vector<int>& points) {
g[0][0] = 1;
CalculatePrefixSum(0);
for (int i = 1; i < 8; ++ i) {
int low_bit = 0;
for (int j = 0; j < 3; ++ j) {
if ((i & (1 << j)) != 0) {
low_bit = j;
break;
}
}
const int other = i ^ (1 << low_bit);
const int point = points[low_bit];
for (int k = 1; k <= MAX_SCORE; ++ k) {
g[i][k] = GetRangeSum(other, k - point, k - 1);
}
CalculatePrefixSum(i);
}
} int GetRangeSum(int mask, int left, int right) {
if (left <= 0) {
return g[mask][right];
}
int result = g[mask][right] - g[mask][left - 1];
if (result < 0) {
result += mod;
}
return result;
}
void Add(int &x, int y) {
x += y;
if (x >= mod) {
x -= mod;
}
}
};

code for problem3

#include <cstring>
#include <iostream>
#include <map>
#include <sstream>
#include <stdio.h>
#include <string>
#include <vector>
using namespace std; #define mod 1000000007
#define MAX_SIZE 2501 int f[MAX_SIZE][MAX_SIZE]; class SRMChallengePhase {
public:
int countWays(vector<string> codersAttempted, vector<string> codersChallenged)
{
const std::string s1 = Concat(codersAttempted);
const std::string s2 = Concat(codersChallenged);
const int n = (int)s1.size();
int A = 0, B = 0, C = 0;
for (int i = 0; i < n; ++i) {
if (s1[i] == 'Y' && s2[i] == 'Y') {
++A;
} else if (s1[i] == 'Y' && s2[i] == 'N') {
++B;
} else if (s1[i] == 'N' && s2[i] == 'Y') {
++C;
}
}
if (B < C) {
return 0;
}
f[0][0] = 1;
for (int i = 1; i <= A + B; ++i) {
for (int j = 0; j <= A; ++j) {
f[i][j] = f[i - 1][j];
if (j > 0) {
Add(f[i][j], (long long)(i - j) * f[i - 1][j - 1] % mod);
}
}
}
int result = f[A + B][A];
for (int i = 1; i <= B - C; ++i) {
result = (long long)result * (n - 1) % mod;
}
for (int i = 2; i <= A; ++i) {
result = (long long)result * i % mod;
}
for (int i = B; i >= 2; --i) {
result = (long long)result * i % mod;
if (i >= B - C + 1) {
result = (long long)result * i % mod;
}
}
return result;
} private:
void Add(int& x, int y)
{
if (y < 0) {
y += mod;
}
x += y;
if (x >= mod) {
x -= mod;
}
}
std::string Concat(const vector<string>& str)
{
std::string s = "";
for (auto x : str) {
s += x;
}
return s;
}
};

  

topcoder srm 520 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. Git常用的命令

    常用 Git 命令清单   作者: 阮一峰 日期: 2015年12月 9日 原文地址:http://www.ruanyifeng.com/blog/2015/12/git-cheat-sheet.ht ...

  2. (转)使用yuicompressor-maven-plugin压缩js及css文件(二)

    本文介绍通过使用yuicompressor-maven-plugin插件实现js及css代码的自动压缩,方便集成到持续集成环境中,如jenkins. 一.配置yuicompressor-maven-p ...

  3. 向量体系结构(2)----SIMD指令集扩展和GPU

    进行SIMD多媒体扩展的设计,源于一个很容易观察到的事实: 许多多媒体应用程序操作的数据类型比对32位处理器进行针对性优化的数据类型更窄一些. 图像三基色,都是8位.音频采样也都是8位和16位来表示. ...

  4. <1>lua编译环境 数据类型和局部变量

    1.编译环境 http://www.lua.org/download.html下载 解压后 bin目录中lua.exe运行   luac.exe编译成lua字节码 2.基本数据类型 整数,小数,布尔值 ...

  5. 4.无监督学习--K-means聚类

    K-means方法及其应用 1.K-means聚类算法简介: k-means算法以k为参数,把n个对象分成k个簇,使簇内具有较高的相似度,而簇间的相似度较低.主要处理过程包括: 1.随机选择k个点作为 ...

  6. Sitecore CMS中配置模板部分

    如何在Sitecore CMS中配置模板部分. 注意: 本教程将扩展于“Sitecore CMS中创建模板”的章节. 配置折叠状态 配置模板部分的折叠状态允许用户选择默认折叠或展开哪些模板部分.此设置 ...

  7. Azure Event Hub 技术研究系列1-Event Hub入门篇

    前两个系列研究了Azure IoT Hub和Azure Messaging.最近准备继续研究Azure Event Hub,即Azure的事件中心.首先, Azure Event Hub的官方介绍: ...

  8. cocos v3.10 下载地址

    官方给出的是在:http://www.cocos2d-x.org/filedown/CocosForWin-v3.10.exe如果下载不了,可以在这里下http://cdn.cocos2d-x.org ...

  9. Spark学习之路 (十)SparkCore的调优之Shuffle调优

    摘抄自https://tech.meituan.com/spark-tuning-pro.html 一.概述 大多数Spark作业的性能主要就是消耗在了shuffle环节,因为该环节包含了大量的磁盘I ...

  10. 性能测试工具Locust,一个开源性能测试工具

    性能测试工具Locust,一个开源性能测试工具使用Python代码来定义用户行为.用它可以模拟百万计的并发用户访问你的系统.1.它与目前主流的LoadRunner和Jmeter玩法都不一样.2.它完全 ...