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 的 ...
随机推荐
- maven本地库更新失败
当我们在项目中遇到有些依赖在第三方仓库特别是maven仓库里面没有的时候我们会怎么办? 答案1.通过私服,上传到公司的一个私服上然后进行下载 答案2.通过本地安装,这样非常方面进行使用,今天我们就采用 ...
- golang sql.DB
数据库 sql.DB连接池需知: sql.DB内置连接池,连接不足时会自动创建新连接,新创建的连接使用sql.Open()时传入的dsn来构造. sql.DBClose时只会关闭连接池中的连接,未归还 ...
- Python Pool
我们在使用Python时,会经常需要使用多进程/多线程的情况,以便提高程序的运行效率,尤其是跟网络进行交互,如使用爬虫时.下面我们将简单看下Python的进程池的创建,map().apply_asyn ...
- supervisor简洁用例
supervisor是什么 superviosr是一个Linux/Unix系统上进程监控和管理的工具,它由python编写,可以用pip安装.supervisor能将一个普通的命令行进程变为后台dae ...
- host映射方法
host映射: host是根据TCP/IP for Windows 的标准来工作的,它的作用是包含IP地址和Host name(主机名)的映射关系,是一个映射IP地址和Host name(主机名)的规 ...
- Linux环境下如何查看内存CPU和GPU使用情况以及界面标题栏实现
查看内存和CPU 单独查看内存使用情况的命令:free -m 查看内存及cpu使用情况的命令:top 也可以安装htop工具,这样更直观, 安装命令如下:sudo apt-ge ...
- Python——杂记
python 最近出错总结: 1.而for..in ..中不要用else if x in y: print else: print2.def fibs(num): ... ...
- 20155303 2016-2017-2 《Java程序设计》第一周学习总结
20155303 2016-2017-2 <Java程序设计>第一周学习总结 教材学习内容总结 浏览教材,根据自己的理解每章提出一个问题 Chapter1 Java平台概论:MyProgr ...
- JSON数据填充表格——(三)
1.定义页面请求JSON的按钮与定义一个带表头的表格 请求数据的按钮 <button class="btn btn-primary search_bar_button floatR& ...
- SVC 工作过程中出现的错误记录(SEO项目)
1.同一のキーを含む項目が既に追加されています.追加的项目中含有重复主键) /seo' アプリケーションでサーバー エラーが発生しました. 同一のキーを含む項目が既に追加されています. 説明: 現在の ...