标签:递增 [1] main getchar size 错题 git ios ==
目录
T1: 80分钟 T2: 100分钟 T3:120分钟
T1:100 T2:100 T3:40
成绩是我线下自己测的
/*
题面牛鬼蛇神??
还有这数据是什么鬼
大概是个划分形的 贪心QWQ
连续的一段1显然可以用两次制造出来(只有连续一个的1除外)
然后 贪心???
先打个n^2暴力吧
是不是我理解错题目了
算了不管了QAQ
转移是单调的吧 ?? 弄个试试 咋弄啊 *(Y*……&*
好像连续两个0不行
*/
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<cmath>
#define M 1000100
#define ll long long
using namespace std;
int read() {
int nm = 0, f = 1;
char c = getchar();
for(; !isdigit(c); c = getchar()) if(c == '-') f = -1;
for(; isdigit(c); c = getchar()) nm = nm * 10 + c - '0';
return nm * f;
}
char s[M];
int a[M], sum[M], n, f[M], sta[M], tp;
int main() {
freopen("twobit.in", "r", stdin), freopen("twobit.out", "w", stdout);
n = read();
scanf("%s", s + 1);
for(int i = 1; i <= n; i++) a[i] = s[n - i + 1] - '0', sum[i] = sum[i - 1] + (a[i] == 0);
if(n <= 300) {
f[0] = 0;
for(int i = 1; i <= n; i++) {
f[i] = f[i - 1] + a[i];
for(int j = 1; j < i; j++) f[i] = min(f[i], f[j - 1] + 2 + sum[i] - sum[j - 1]);
}
cout << f[n] << "\n";
} else {
int ans = n - sum[n], tmp = 0;
int now = 1;
while(1) {
while(!a[now] && now <= n) now++;
tp = 0;
if(now > n) break;
while(a[now] || a[now + 1]) sta[++tp] = now++;
tmp += min(tp - (sum[sta[tp]] - sum[sta[1] - 1]), 2 + sum[sta[tp]] - sum[sta[1] - 1]);
}
ans = min(ans, tmp);
cout << ans << "\n";
}
return 0;
}
/*
暴力n^2
发现类似于前缀的那个东西是可以优化的, 第一次min值是个V形线, 取min之后就是_/的样子, 之后若加入的点在前面min图像就会变成\_/还有另外一种
发现之后的加入都是形成一个下凸的东西, 想办法维护它,发现维护交点就可以了
*/
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<cmath>
#define M 1000010
#define N 1010
#define ll long long
using namespace std;
int read() {
int nm = 0, f = 1;
char c = getchar();
for(; !isdigit(c); c = getchar()) if(c == '-') f = -1;
for(; isdigit(c); c = getchar()) nm = nm * 10 + c - '0';
return nm * f;
}
int f[N];
int n, a[M], maxx, minn[N];
int ab(int x) {
return x > 0 ? x : -x;
}
ll ans;
priority_queue<int, vector<int>, greater<int> > que;
int main() {
freopen("lis.in", "r", stdin);freopen("lis.out", "w", stdout);
n = read();
for(int i = 1; i <= n; i++) a[i] = read(), maxx = max(maxx, a[i]);
if(n <= 1000 && maxx <= 1000) {
memset(f, 0x3e, sizeof(f));
for(int i = 0; i <= maxx; i++) f[i] = ab(i - a[1]);
for(int i = 2; i <= n; i++) {
memset(minn, 0x3e, sizeof(minn));
for(int j = maxx; j >= 0; j--) minn[j] = min(minn[j + 1], f[j]);
memset(f, 0x3e, sizeof(f));
for(int j = 0; j <= maxx; j++) f[j] = minn[j] + ab(a[i] - j);
}
int ans = 0x3e3e3e3e;
for(int i = 0; i <= maxx; i++) ans = min(ans, f[i]);
cout << ans << "\n";
return 0;
} else {
for(int i = 1; i <= n; i++) {
que.push(a[i]);
if(a[i] > que.top()) {
ans += a[i] - que.top();
que.pop();
que.push(a[i]);
}
}
cout << ans << "\n";
}
return 0;
}
/*
只能打暴力么QAQ
好像能加个记忆化 OVO
仅此而已了, 离散出所有的差, 然后按照大小分类 , 实际上只有n + 1类, 然后记忆化dfs一下 (n + 1) (2 ^ n)
能不能把状态压缩的那个状态去掉呢??
md 题面除以2需要自己补充??? zzzzzzzzzz
好像不能只记录差, 离散化不了
弃疗了
话说记忆化有啥用??? 枚举全排列不就完了
好的其实这个题目题面写错了
要求出所有的相当于
*/
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<cmath>
#define ll long long
#define M 66
using namespace std;
int read() {
int nm = 0, f = 1;
char c = getchar();
for(; !isdigit(c); c = getchar()) if(c == '-') f = -1;
for(; isdigit(c); c = getchar()) nm = nm * 10 + c - '0';
return nm * f;
}
const int mod = 1000000007;
int note[66];
int sta[111111], tp;
int a[M], n;
int f[22][1 << 20];
bool vis[22][1 << 20];
bool gt[99];
int b[M];
void add(int &x, int y) {
x += y;
x -= x >= mod ? mod : 0;
}
int mp[1111111];
int dfs(int now, int bt) {
if(now == n) return 1;
if(now >= 2) {
int op = 2 * b[now - 1] - b[now - 2];
int zz = mp[op + 100000];
f[zz][bt] = 0;
for(int i = zz; i <= n; i++) {
if(!gt[i]) {
gt[i] = true;
b[now] = a[i];
add(f[zz][bt], dfs(now + 1, bt | (1 << (i - 1))));
gt[i] = false;
}
}
return f[zz][bt];
} else {
int ans = 0;
for(int i = 1; i <= n; i++) {
if(!gt[i]) {
gt[i] = true;
b[now] = a[i];
add(ans, dfs(now + 1, bt | (1 << (i - 1))));
gt[i] = false;
}
}
return ans;
}
}
int main() {
//freopen("squence.in", "r", stdin), freopen("squence.out", "w", stdout);
n = read();
if(n > 20) {
cout << "20020216";
return 0;
}
if(n <= 2) {
cout << n << "\n";
return 0;
}
else
for(
for(int i = 1; i <= n; i++) a[i] = read();
sort(a + 1, a + n + 1);
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
if(i == j) continue;
sta[++tp] = 2 * a[i] - a[j];
}
}
a[n + 1] = 0x3e3e3e3e;
sort(sta + 1, sta + tp + 1);
for(int i = 1; i <= tp; i++) {
for(int j = 1; j <= n + 1; j++) {
if(a[j] >= sta[i]) {
mp[sta[i] + 100000] = j;
break;
}
}
}
cout << dfs(0, 0) << "\n";
return 0;
}
/*
3
1 2 0
*/
/*
*/
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<cmath>
#define M 66
#define ll long long
using namespace std;
const int mod = 1000000007;
ll read() {
ll nm = 0, f = 1;
char c = getchar();
for(; !isdigit(c); c = getchar()) if(c == '-') f = -1;
for(; isdigit(c); c = getchar()) nm = nm * 10 + c - '0';
return nm * f;
}
void add(int &x, int y) {
x += y;
x -= x >= mod ? mod : 0;
}
int f[M][M][M][M];
int a[M], n, ans;
int main() {
//freopen(".in", "r", stdin), freopen(".out", "w", stdout);
n = read();
for(int i = 1; i <= n; i++) a[i] = read();
sort(a + 1, a + n + 1);
int now = 0, fac = 1;
while(a[now + 1] == a[1]) now++, fac = 1ll * fac * now % mod;
f[0][now][0][now] = 1;
for(int i = 0; i <= n; i++)
for(int j = i; j <= n; j++)
for(int k = 0; k <= n; k++)
for(int l = k; l <= n; l++) {
if(!f[i][j][k][l]) continue;
int now = max(i, max(j, max(k, l))) + 1;
if(now == n + 1) add(ans, f[i][j][k][l]);
else {
if(i == 0 || a[now] - a[j] >= a[j] - a[i]) add(f[j][now][k][l], f[i][j][k][l]);
if(k == 0 || a[now] - a[l] >= a[l] - a[k]) add(f[i][j][l][now], f[i][j][k][l]);
}
}
cout << 1ll * ans * fac % mod << "\n";
return 0;
}
标签:递增 [1] main getchar size 错题 git ios ==
原文地址:https://www.cnblogs.com/luoyibujue/p/10116869.html