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;
}
posted @ 2018-03-17 16:59  v9fly  阅读(157)  评论(0编辑  收藏  举报