2016-2017 ACM-ICPC Pacific Northwest Regional Contest (Div. 2) 题解
【题目链接】
最长公共子序列。保留最长公共子序列,剩余的删除或者补足即可。
#include <bits/stdc++.h>
using namespace std; const int maxn = 1e5 + 10;
char s[maxn];
char t[maxn];
int dp[100][100]; int main() {
scanf("%s", s);
for(int i = 0; i < 26; i ++) {
t[i] = i + 'a';
t[i + 1] = 0;
}
int lens = strlen(s);
int lent = strlen(t);
for(int i = 1; i <= lens; i ++) {
for(int j = 1; j <= lent; j ++) {
if(s[i - 1] == t[j - 1]) dp[i][j] = dp[i - 1][j - 1] + 1;
else dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
}
}
printf("%d\n", 26 - dp[lens][lent]);
return 0;
}
暴力。枚举哪几个一定用,去剩余的那些里面枚举是否可以凑出和这几个一样的。
#include <bits/stdc++.h>
using namespace std; const int maxn = 1e5 + 10;
int n, m;
long long a[maxn], b[maxn];
long long ans[maxn];
long long p[maxn];
long long sum[maxn];
int sz, cnt;
long long B[maxn];
long long sumB[maxn]; int lowbit(int x) {
return x & (-x);
} int main() {
cin >> n >> m;
for(int i = 0; i < n; i ++) cin >> a[i];
for(int i = 0; i < m; i ++) cin >> b[i];
for(int i = 1; i < (1 << m); i ++) {
for(int j = 0; j < m; j ++) {
if((1 << j) & i) sum[i] += b[j];
}
}
for(int i = 0; i < (1 << m); i ++) {
sz = 0;
for(int j = 0; j < m; j ++) {
if((1 << j) & i) continue;
B[sz ++] = b[j];
}
// sum[i];
if(sum[i] == 0) {
p[cnt ++] = sum[i];
continue;
}
sumB[0] = 0;
for(int j = 0; j < sz; j ++) {
sumB[1 << j] = B[j];
}
for(int j = 1; j < (1 << sz); j ++) {
sumB[j] = sumB[j - lowbit(j)] + sumB[lowbit(j)];
if(sumB[j] == sum[i]) {
p[cnt ++] = sum[i];
break;
}
}
}
sz = 0;
for(int i = 0; i < cnt; i ++) {
for(int t = 0; t < n; t ++) {
ans[sz ++] = p[i] * 2 + a[t];
}
}
sort(ans, ans + sz);
for(int i = 0; i < sz; i ++) {
if(i >= 1 && ans[i] == ans[i - 1]) continue;
printf("%lld\n", ans[i]);
} return 0;
} /*
2 5
100 110
5 5 1 4 6 */
记$f[i][x][y]$表示操作了前$i$个指令,当前在$(x,y)$位置的最小费用。分析可以发现是一个边权只有$0$和$1$的最短路问题。
#include<bits/stdc++.h>
using namespace std; const int maxn = 60;
int dir[4][2] = {
{-1, 0},
{0, 1},
{1, 0},
{0, -1},
}; int n, m;
char s[maxn][maxn];
char op[maxn];
int len;
int dp[maxn][maxn][maxn];
int f[maxn][maxn][maxn];
int sx, sy, ex, ey; int out(int x, int y) {
if(x < 0 || x >= n) return 1;
if(y < 0 || y >= m) return 1;
return 0;
} int Hash(int a, int x, int y) {
return a * 10000 + x * 100 + y;
} void Get(int st, int &a, int &x, int &y) {
y = st % 100;
st = st / 100;
x = st % 100;
st = st / 100;
a = st;
} void work() {
queue<int> q;
dp[0][sx][sy] = 0;
f[0][sx][sy] = 1;
q.push(Hash(0, sx, sy));
while(!q.empty()) {
int st = q.front();
q.pop();
int a, x, y;
Get(st, a, x, y);
f[a][x][y] = 0; /* insert */
for(int i = 0; i < 4; i ++) {
int tx = x + dir[i][0];
int ty = y + dir[i][1];
if(out(tx, ty)) continue;
if(s[tx][ty] == '#') continue;
if(dp[a][tx][ty] > dp[a][x][y] + 1) {
dp[a][tx][ty] = dp[a][x][y] + 1;
if(f[a][tx][ty] == 0) {
f[a][tx][ty] = 1;
q.push(Hash(a, tx, ty));
}
}
} /* del */
if(a < len) {
if(dp[a + 1][x][y] > dp[a][x][y] + 1) {
dp[a + 1][x][y] = dp[a][x][y] + 1;
if(f[a + 1][x][y] == 0) {
f[a + 1][x][y] = 1;
q.push(Hash(a + 1, x, y));
}
}
} /* use */
if(a < len) {
int d;
if(op[a] == 'U') d = 0;
if(op[a] == 'R') d = 1;
if(op[a] == 'D') d = 2;
if(op[a] == 'L') d = 3; int tx = x + dir[d][0];
int ty = y + dir[d][1];
if(out(tx, ty) || s[tx][ty] == '#') {
tx = x;
ty = y;
}
if(dp[a + 1][tx][ty] > dp[a][x][y]) {
dp[a + 1][tx][ty] = dp[a][x][y];
if(f[a + 1][tx][ty] == 0) {
f[a + 1][tx][ty] = 1;
q.push(Hash(a + 1, tx, ty));
}
}
}
}
} int main() {
scanf("%d%d", &n, &m);
for(int i = 0; i < n; i ++) {
scanf("%s", s[i]);
}
scanf("%s", op);
len = strlen(op);
for(int i = 0; i < n; i ++) {
for(int j = 0; j < m; j ++) {
if(s[i][j] == 'R') sx = i, sy = j;
if(s[i][j] == 'E') ex = i, ey = j;
for(int k = 0; k <= len; k ++) {
dp[k][i][j] = 100000;
}
}
}
work();
int ans = 100000;
for(int i = 0; i <= len; i ++) {
ans = min(ans, dp[i][ex][ey]);
}
printf("%d\n", ans);
return 0;
} /*
3 3
R..
.#.
..E
LRDD 2 4
R.#.
#..E
RRUUDDRRUUUU
*/
贪心。每一个区间看,贪心靠后放$1$即可。
#include<bits/stdc++.h>
using namespace std; const int maxn = 1e5 + 10;
int f[maxn];
int n, k, r; int main() {
scanf("%d%d%d", &n, &k, &r);
for(int i = 1; i <= k; i ++) {
int x;
scanf("%d", &x);
f[x] = 1;
}
int ans = 0;
int sum = 0;
for(int i = 1; i <= r; i ++) {
sum += f[i];
}
int R = r;
while(sum < 2) {
if(f[R]) R --;
else {
sum ++;
f[R] = 1;
ans ++;
R --;
}
}
for(int i = r + 1; i <= n; i ++) {
sum -= f[i - r];
sum += f[i];
int L = i - r + 1;
int R = i;
while(sum < 2) {
if(f[R]) R --;
else {
sum ++;
f[R] = 1;
ans ++;
R --;
}
}
}
printf("%d\n", ans);
return 0;
}
优先队列。
#include <bits/stdc++.h>
using namespace std; int n, k;
long long a[500];
priority_queue<long long> p; int main() {
scanf("%d%d", &n, &k);
for(int i = 1; i <= n; i ++) {
cin >> a[i];
}
long long ans = 0;
long long time = 0;
for(int i = 1; i <= k; i ++) {
p.push(-a[i]);
}
for(int i = k + 1; i <= n; i ++) {
long long u = -p.top();
p.pop();
time += u;
ans += time;
p.push(-a[i]);
}
while(!p.empty()) {
long long u = -p.top();
p.pop();
time += u;
ans += time;
}
cout << ans << endl;
return 0;
}
水题。
#include <bits/stdc++.h>
using namespace std; const int maxn = 1e5 + 10;
char s[maxn]; int main() {
int a, b, c;
cin >> a;
cin >> s;
cin >> b;
cin >> s;
cin >> c;
if(a + b == c) puts("YES");
else puts("NO");
return 0;
}
模拟。
#include <bits/stdc++.h>
using namespace std; const int maxn = 1000;
char s[maxn][maxn]; int main() {
int n, m;
scanf("%d%d", &n, &m);
for(int i = 0; i < n; i ++) {
scanf("%s", s[i]);
}
for(int i = n - 2; i >= 0; i --) {
for(int j = 0; j < m; j ++) {
if(s[i][j] != 'o') continue;
int x = i;
for(int k = i + 1; k < n; k ++) {
if(s[k][j] == '.') x = k;
else break;
}
s[i][j] = '.';
s[x][j] = 'o';
}
}
for(int i = 0; i < n; i ++) {
printf("%s\n", s[i]);
}
return 0;
} /*
3 3
ooo
#..
..# 4 2
oo
oo
o.
..
*/
从每一个未被遍历过的$L$开始遍历,$C$当做$L$。
#include <bits/stdc++.h>
using namespace std; const int maxn = 1010;
char s[maxn][maxn];
int n, m;
int ans; int f[maxn][maxn];
int dir[4][2] = {
{0, -1},
{0, 1},
{1, 0},
{-1, 0},
}; int out(int x, int y) {
if(x < 0 || x >= n) return 1;
if(y < 0 || y >= m) return 1;
return 0;
} void dfs(int x, int y) {
f[x][y] = 1;
for(int i = 0; i < 4; i ++) {
int tx = x + dir[i][0];
int ty = y + dir[i][1];
if(out(tx, ty)) continue;
if(s[tx][ty] == 'W') continue;
if(f[tx][ty]) continue;
dfs(tx, ty);
}
} int main() {
scanf("%d%d", &n, &m);
for(int i = 0; i < n; i ++) {
scanf("%s", s[i]);
}
for(int i = 0; i < n; i ++) {
for(int j = 0; j < m; j ++) {
if(f[i][j]) continue;
if(s[i][j] == 'L') {
dfs(i, j);
ans ++;
}
}
}
cout << ans << endl;
return 0;
} /*
4 5 CCCCC CCCCC CCCCC CCCCC
3 2 LW CC WL
*/
二分。和这里的F题一样的做法,不再赘述。
#include <bits/stdc++.h>
using namespace std; int T, n, k;
const int maxn = 1e5 + 10;
long long a[maxn]; int check(long long x) {
long long p = 0;
for(int i = 1; i <= n; i ++) {
p = p + min(x, a[i]);
}
if(p >= x * k) return 1;
return 0;
} int main() { scanf("%d", &n);
k = 2;
for(int i = 1; i <= n; i ++) {
scanf("%lld", &a[i]);
}
long long L = 0;
long long R = 1e12;
long long ans = 0;
while(L <= R) {
long long mid = (L + R) / 2;
if(check(mid)) ans = mid, L = mid + 1;
else R = mid - 1;
}
printf("%lld\n", ans); return 0;
}
贪心。原点左侧和右侧分开计算。每一侧计算的时候由远及近进行操作即可。
#include <bits/stdc++.h>
using namespace std; const int maxn = 1e5 + 10;
struct X {
long long x;
long long m;
}s[maxn];
int n;
long long k; bool cmp(const X& a, const X& b) {
return a.x < b.x;
} int main() {
scanf("%d%lld", &n, &k);
for(int i = 1; i <= n; i ++) {
scanf("%lld%lld", &s[i].x, &s[i].m);
}
sort(s + 1, s + 1 + n, cmp);
long long ans = 0;
int p;
if(s[1].x <= 0) {
for(int i = 1; i <= n; i ++) {
if(s[i].x <= 0) p = i;
}
while(1) {
int now = -1;
for(int i = 1; i <= p; i ++) {
if(s[i].m) {
now = i;
break;
}
}
if(now == -1) break;
if(s[now].m >= k) {
long long ci = s[now].m / k;
ans = ans - ci * s[now].x;
s[now].m = s[now].m % k;
} else {
long long tmp = k;
ans = ans - s[now].x;
while(tmp) {
if(now > p) break;
long long A = min(tmp, s[now].m);
tmp = tmp - A;
s[now].m -= A;
now ++;
}
}
}
}
p = -1;
for(int i = 1; i <= n; i ++) {
if(s[i].x > 0) {
p = i;
break;
}
}
if(p != -1) {
while(1) {
int now = -1;
for(int i = p; i <= n; i ++) {
if(s[i].m) {
now = i;
}
}
if(now == -1) break;
if(s[now].m >= k) {
long long ci = s[now].m / k;
ans = ans + ci * s[now].x;
s[now].m = s[now].m % k;
} else {
long long tmp = k;
ans = ans + s[now].x;
while(tmp) {
if(now < p) break;
long long A = min(tmp, s[now].m);
tmp = tmp - A;
s[now].m -= A;
now --;
}
}
}
}
cout << ans * 2LL << endl;
return 0;
} /*
4 10
-7 5
-2 3
5 7
9 5 7 1
9400000 10000000
9500000 10000000
9600000 10000000
9700000 10000000
9800000 10000000
9900000 10000000
10000000 10000000
*/
模拟。操作的次数越多,答案精度越高。
#include <bits/stdc++.h>
using namespace std; const int maxn = 1000;
int a[maxn], b[maxn]; int main() {
double ping = 0;
double win = 0;
for(int i = 1; i <= 6; i ++) cin >> a[i];
for(int i = 1; i <= 6; i ++) cin >> b[i];
for(int i = 1; i <= 6; i ++) {
for(int j = 1; j <= 6; j ++) {
if(a[i] == b[j]) ping ++;
if(a[i] > b[j]) win ++;
}
}
ping /= 36.0;
win /= 36.0;
double ans = 0.0;
double x = 1.0;
for(int i = 1; i <= 1000000; i ++) {
ans = ans + x * win;
x = x * ping;
}
printf("%.5f\n", ans);
return 0;
}
暴力枚举所有情况。
#include <bits/stdc++.h>
using namespace std; const int maxn = 5e5 + 10;
int n, m;
int a[maxn], b[maxn];
int t[maxn]; int A[maxn], B[maxn]; int main() { cin >> a[0] >> b[0];
cin >> a[1] >> b[1];
cin >> a[2] >> b[2]; t[0] = 0, t[1] = 1, t[2] = 2; int ok = 0; do {
// printf("%d %d %d\n", t[0], t[1], t[2]);
for(int i = 0; i < 8; i ++) {
for(int j = 0; j < 3; j ++) {
if((i << j) & i) {
B[j] = a[t[j]];
A[j] = b[t[j]];
} else {
A[j] = a[t[j]];
B[j] = b[t[j]];
}
} // 1
if(A[0] == A[1] && A[0] == A[2]
&& B[0] + B[1] + B[2] == A[0]) ok = 1; // 2
if(B[0] == B[1] && B[0] == B[2]
&& A[0] + A[1] + A[2] == B[0]) ok = 1; // 3
if(B[1] + B[2] == B[0] && A[1] == A[2]
&& A[1] + A[0] == B[0]) ok = 1; // 5
if(B[1] == B[2] && A[1] + A[2] == A[0]
&& A[0] == B[0] + B[1]) ok = 1; }
} while(next_permutation(t, t + 3)); if(ok) puts("YES");
else puts("NO"); return 0;
}
记录以每个位置为结尾的且在波峰以及波谷的最长序列长度,和LIS一样转移即可。
#include <bits/stdc++.h>
using namespace std; const int maxn = 2000000; int n;
int d[maxn];
int dp[maxn][2]; int main() {
cin >> n;
for(int i = 1; i <= n; i ++) {
cin >> d[i];
}
int ans = 0;
for(int i = 1; i <= n; i ++) {
int mx = 0;
// dp[i][0];
for(int j = 1; j < i; j ++) {
if(d[j] > d[i]) mx = max(mx, dp[j][1]);
}
dp[i][0] = mx + 1;
ans = max(ans, dp[i][0]); mx = 0;
// dp[i][1];
for(int j = 1; j < i; j ++) {
if(d[j] < d[i]) mx = max(mx, dp[j][0]);
}
dp[i][1] = mx + 1;
ans = max(ans, dp[i][1]);
}
cout << ans << endl;
return 0;
}
2016-2017 ACM-ICPC Pacific Northwest Regional Contest (Div. 2) 题解的更多相关文章
- 2018 ICPC Pacific Northwest Regional Contest I-Inversions 题解
题目链接: 2018 ICPC Pacific Northwest Regional Contest - I-Inversions 题意 给出一个长度为\(n\)的序列,其中的数字介于0-k之间,为0 ...
- 2018-2019 ACM-ICPC Pacific Northwest Regional Contest (Div. 1)
2018-2019 ACM-ICPC Pacific Northwest Regional Contest (Div. 1) 思路: A Exam 思路:水题 代码: #include<bits ...
- Contest Setting 2018 ICPC Pacific Northwest Regional Contest dp
题目:https://vj.69fa.cn/12703be72f729288b4cced17e2501850?v=1552995458 dp这个题目网上说是dp+离散化这个题目要对这些数字先处理然后进 ...
- 2015-2016 ACM-ICPC Pacific Northwest Regional Contest (Div. 2) S Surf
SurfNow that you've come to Florida and taken up surng, you love it! Of course, you've realized that ...
- 2016-2017 ACM-ICPC Pacific Northwest Regional Contest (Div. 1) Solution
A:Alphabet Solved. 签. #include<bits/stdc++.h> using namespace std; ]; ]; int main(){ scanf(); ...
- 2018-2019 ACM-ICPC Pacific Northwest Regional Contest (Div. 1) Solution
A:Exam Solved. 温暖的签. #include<bits/stdc++.h> using namespace std; ; int k; char str1[maxn], st ...
- 2016-2017 ACM-ICPC Pacific Northwest Regional Contest (Div. 1) K Tournament Wins
题目链接:http://codeforces.com/gym/101201 /* * @Author: lyucheng * @Date: 2017-10-22 14:38:52 * @Last Mo ...
- 2017-2018 ACM-ICPC Pacific Northwest Regional Contest (Div. 1)
A. Odd Palindrome 所有回文子串长度都是奇数等价于不存在长度为$2$的偶回文子串,即相邻两个字符都不同. #include<cstdio> #include<cstr ...
- 2017-2018 ACM-ICPC Pacific Northwest Regional Contest (Div. 1) B - Enlarging Enthusiasm dp好题
B - Enlarging Enthusiasm 感觉做到过好多的dp题都会和单调性结合在一起. 思路:dp[ s ][ pre ][ res ] 表示的是已选择了s,上一个是pre, 还有res 的 ...
随机推荐
- MongoDB 及 Mysql 背后的 B/B+树
索引是数据库常见的数据结构,每个后台开发人员都应该对索引背后的数据结构有所了解. 本文通过分析B-Tree及B-/+Tree数据结构及索引性能分析及磁盘存取原理尝试着回答一下问题: 为什么B-Tree ...
- MapReduce (MRV1)设计理念与基本架构
MapReduce 是一个分布式计算框架,主要由两部分组成:编程模型和运行时环境. 其中,编程模型为用户提供了非常易用的编程接口,用户只需要像编写串行程序一样实现几个简单的函数即可实现一个分布式程序, ...
- 关于ES6 Class语法相关总结
关于ES6,其实网上已经有很多的资料可供查询,教程可参考阮一峰大神的ES6入门,本文只是对Class这一语法做一个总结: 一.Class基本语法 constructor方法 constructor是类 ...
- IE6下面的css调试工具
在开发过程中,代码部分实现之后,就要着手于前台展示部分的界面,公司的美工又是新手,无奈,只有自己慢慢调了,但IE6之前的版本都没有好的调试工具,后来在网上搜索了一个 IE Developer Tool ...
- Linux基础-awk、变量、运算符、if
awk 程序的运行就是一些列状态的变量->用变量值的变化去表示 以字母或下划线开头,剩下的部分可以是:字母.数字.下划线. 最好遵循下述规范: 1.以字母开头2.使用中划线或者下划线做单词的连接 ...
- UNIX环境高级编程 第5章 标准I/O库
本章是关于C语言标准I/O库的,之所以在UNIX类系统的编程中会介绍C语言标准库,主要是因为UNIX和C之间具有密不可分的关系.由于UNIX系统存在很多实现,而每个实现都有自己的标准I/O库,为了统一 ...
- lucene总结——(十七)
(01)rownum和rowid有何区别? rownum在表结构中是看不见的,只能在select中明确写出rownum方可显示 rownum与不同的表绑定在一起,每张表都有自已的r ...
- Struts2笔记3--获取ServletAPI和OGNL与值栈
获取ServletAPI: 第一种方式: //在request域中放入属性req,暂且认为getContext()获取的是request域空间,但实际不是 ActionContext.getConte ...
- Centos6.5下搭建nagios详解
一.LAMP环境部署 1.安装php 1.安装yum源 rpm -Uvh http://download.fedoraproject.org/pub/epel/6/x86_64/epel-releas ...
- BZOJ 3510 - 首都 「 $LCT$ 动态维护树的重心」
这题 FlashHu 的优化思路值得借鉴 前置引理 树中所有点到某个点的距离和中,到重心的距离和是最小的. 把两棵树通过某一点相连得到一颗新的树,新的树的重心必然在连接原来两棵树重心的路径上. 一棵树 ...