Educational Codeforces Round 39 (Rated for Div. 2) D dp E 贪心
最近学了一下markdown,挺好玩的,以后博客就用 markdown 编辑了 +*+
Educational Codeforces Round 39 (Rated for Div. 2)
D. Timetable
题意:有 n天, m 节课,最多逃 k 节课。每天这个人会从第一节课待到最后一节课,问最少在学校待多久。
tags: dp[i][j] 前 i 天逃了 j 节课最少待多久。 dp[i][j] = min(dp[i][j] , dp[i-1][k] + get_min(i, j-k) ) 。 get_min(i, j-k) 表示第 i 天逃了 j-k 节课最少要待多久,这个预处理就好。
// Edu 39 D
#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define rep(i,a,b) for (int i=a; i<=b; ++i)
#define per(i,b,a) for (int i=b; i>=a; --i)
#define mes(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define MP make_pair
#define PB push_back
#define fi first
#define se second
typedef long long ll;
const int N = 505;
int n, m, k, f[N], g[N][N], dp[N][N];
char s[N];
int main()
{
scanf("%d%d%d", &n, &m, &k);
int sum1 = 0;
rep(i,1,n)
{
scanf("%s", s+1);
int sum=0;
rep(j,1,m) if(s[j]=='1') f[++sum]=j;
sum1 += sum;
rep(j,0,sum-1) g[i][j]=INF;
rep(j,0,sum-1) rep(l,0,j)
{
if(sum-(j-l)>0)
g[i][j] = min(g[i][j], f[sum-(j-l)]-f[l+1]+1);
}
}
if(sum1<=k) return printf("0\n"), 0;
rep(i,1,n) rep(j,0,k)
{
dp[i][j] = INF;
rep(l,0,j)
dp[i][j] = min(dp[i][j], dp[i-1][j-l]+g[i][l]);
}
printf("%d\n", dp[n][k]);
return 0;
}
E. Largest Beautiful Number
题意:定义完美数为:长度为偶数,且重新排列后可以重组成回文串。 t 个询问,每次询问有一个 s,求小于 s 的最大的完美数。
tags:就是贪心。。
从后往前,每次假设把第 i 位变小,然后判断一下 [ i+1 到 len ] 能否把前面出现奇数次的数给出补上一次,多余的就添 9。
// 39 E
#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define rep(i,a,b) for (int i=a; i<=b; ++i)
#define per(i,b,a) for (int i=b; i>=a; --i)
#define mes(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define MP make_pair
#define PB push_back
#define fi first
#define se second
typedef long long ll;
const int N = 200005;
int T, cnt[10], sum, len;
char s[N];
void Init() {
rep(i,0,9) cnt[i]=0;
sum = 0;
len = strlen(s+1);
rep(i,1,len) ++cnt[s[i]-'0'];
rep(i,0,9) if(cnt[i]&1) ++sum;
}
bool solve()
{
per(i, len, 1)
{
if(cnt[s[i]-'0']&1) --sum;
--cnt[s[i]-'0'];
if(cnt[s[i]-'0']&1) ++sum;
for(int j=s[i]-'0'-1; j>=0; --j)
{
if(i==1 && j==0) continue;
if(cnt[j]&1) --sum;
++cnt[j];
if(cnt[j]&1) ++sum;
if(sum <= len-i) // YES
{
per(l, len, i+1)
{
if(sum==0) {
s[l]='9', ++cnt[9];
continue;
}
rep(k,0,9) if(cnt[k]&1) {
--sum, ++cnt[k];
s[l] = '0'+k;
break;
}
}
s[i] = '0'+j;
rep(l,1,len) putchar(s[l]); puts("");
return true;
}
if(cnt[j]&1) --sum;
--cnt[j];
if(cnt[j]&1) ++sum;
}
}
return false;
}
int main()
{
scanf("%d", &T);
while(T--)
{
scanf("%s", s+1);
Init();
if(len&1) {
rep(i,1,len-1) putchar('9');
puts("");
}
if(!solve()) {
rep(i,1,len-2) putchar('9');
puts("");
}
}
return 0;
}