zoukankan      html  css  js  c++  java
  • 贪心

    https://vjudge.net/contest/269890#problem/E

    加油问题,可以用优先队列

    https://vjudge.net/contest/228508#problem/B

    rmq问题,贪心做

    大意:给你一个数字串,要你删除m个数字后所得的最小数字串是多少。思路:转换思想选出n-m个使其最小,178543选2个使其最小,第1个数从1-4中选,选1,第2个数从上个数+1位置开始选,即从7-3中开始选,选3,答案13

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #define N 1008
    #define LL long long
    using namespace std;
    int dp[N][30];
    char s[N];int s1[N];
    void RMQ(int n)
    {
        int i,j;
        for(j=1; 1<<j<=n; j++)
            for(i=0; i+(1<<j)-1<n; i++)
                dp[i][j]=min(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
    }
    int main()
    {
        int m,i,a,b;
        while(~scanf("%s%d",s,&m))
        {
            int cat=0;
            int len=strlen(s);
            if(m>len)
            {
                puts("0");
                continue;
            }
            else if(m<=0)
            {
                puts(s);
                continue;
            }
            for(i=0; i<len; i++)
                dp[i][0]=s[i]-'0';
            RMQ(len);
            m=len-m;//选m个数
            a=0,b=len-m;从[a,b]区间选
            //LL sum=0;长度1000可能超限,所以用字符数组储存
            while(m--)
            {
                int k=log(b-a+1.0)/log(2.0);
                int num=min(dp[a][k],dp[b-(1<<k)+1][k]);
                s1[cat++]=num;
                for(i=a; i<=b; i++)
                {
                    if(s[i]==num+'0')
                        break;
                }
                a=i+1,b++;
            }
            for(i=0; i<cat; i++)
            {
                if(s1[i]!=0)
                {
                    break;
                }
            }
    //如果全是零。
    if(i==cat) { puts("0"); continue; } for(i; i<cat; i++) printf("%d",s1[i]); cout<<endl; } return 0; }

    https://vjudge.net/contest/282940#problem/I

    专题链接。

    Jury Meeting

     CodeForces - 853B 

    https://blog.csdn.net/my_sunshine26/article/details/77876193

    一群专家要到某个地方一起带K天,每个城市一个专家,然后每个城市到开会地点有n个来的航班,回去的航班,求最小花费。

    先按时间 排序,先求每个点的(如果这个点的时候可以是每个专家都到达,则算出这个和记录下来)

    然后从后面算起,如果某个点可以每个专家都回去,则算出这个和记录下来,

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    
    using namespace std;
    const int maxm = 1e5 + 5;
    const int maxm1 = 1e6 + 5;
    typedef long long ll;
    int n, m, k;
    struct NODE {
    int d, u, v, w;
    bool operator < (const NODE &a) const {
    return d < a.d;
    }
    } node[maxm];
    ll dis[maxm], sum1[maxm1], sum2[maxm1];
    
    int main() {
    scanf("%d%d%d", &n, &m, &k);
    int Max = 0, cnt = n;
    for(int i = 1; i <= m; i++) {
        scanf("%d%d%d%d", &node[i].d, &node[i].u, &node[i].v, &node[i].w);
        Max = max(Max, node[i].d);
    }
    sort(node + 1, node + m + 1);
    for(int i = 1; i <= m; i++) {
        int index = node[i].d;
        if(node[i].u != 0 && node[i].v == 0) {
            if(dis[ node[i].u ] == 0) {
                dis[ node[i].u ] = node[i].w;
                cnt--;
                if(!cnt) {
                    ll sum = 0;
                    for(int j = 1; j <= n; j++) {
                        sum += dis[j];
                    }
                    sum1[index] = sum;
                }
            }
            else if(dis[ node[i].u ] > node[i].w) {
                dis[ node[i].u ] = node[i].w;
                if(!cnt) {
                    ll sum = 0;
                    for(int j = 1; j <= n; j++) {
                        sum += dis[j];
                    }
                    sum1[index] = sum;
                }
            }
        }
    }
    if(cnt != 0) {
        printf("-1
    ");
        return 0;
    }
    memset(dis, 0, sizeof(dis));
    cnt = n;
    for(int i = m; i >= 1; i--) {
        int index = node[i].d;
        if(node[i].u == 0 && node[i].v != 0) {
            if(dis[ node[i].v ] == 0) {
                dis[ node[i].v ] = node[i].w;
                cnt--;
                if(!cnt) {
                    ll sum = 0;
                    for(int j = 1; j <=n; j++) {
                        sum += dis[j];
                    }
                    sum2[index] = sum;
                }
            }
            else if(dis[ node[i].v ] > node[i].w) {
                dis[ node[i].v ] = node[i].w;
                if(!cnt) {
                    ll sum = 0;
                    for(int j = 1; j <= n; j++) {
                        sum += dis[j];
                    }
                    sum2[index] = sum;
                }
            }
        }
    }
    if(cnt != 0) {
        printf("-1
    ");
        return 0;
    }
    for(int i = 1; i <= Max; i++) {
        if(!sum1[i]) sum1[i] = sum1[i - 1];
        else if(sum1[i] > 0 && sum1[i - 1] > 0) {
            sum1[i] = min(sum1[i], sum1[i - 1]);
        }
    }
    for(int i = Max; i >= 1; i--) {
        if(!sum2[i]) sum2[i] = sum2[i + 1];
        else if(sum2[i] > 0 && sum2[i + 1] > 0) {
            sum2[i] = min(sum2[i], sum2[i + 1]);
        }
    }
    ll res = 1e14;
    for(int i = 1; i <= Max, i + k + 1 <= Max; i++) {
        if(sum1[i] != 0 && sum2[i + k + 1] != 0) {
            res = min(res, sum1[i] + sum2[i + k + 1]);
        }
    }
    if(res == 1e14) printf("-1
    ");
    else printf("%lld
    ", res);
    
    return 0;
    }
  • 相关阅读:
    codeforce1029B B. Creating the Contest(简单dp,简单版单调栈)
    spfa算法
    spfa算法
    HDU King (非连通图的差分约束,经典好题)
    HDU King (非连通图的差分约束,经典好题)
    差分约束系统相关证明(存在负环则无解证明)
    Java API 读取HDFS的单文件
    採用邻接矩阵创建图
    旧金山攻略
    一个jeecg整合activiti的学习样例,源代码下载
  • 原文地址:https://www.cnblogs.com/downrainsun/p/9984330.html
Copyright © 2011-2022 走看看