• 第三届ACM山东省赛F题_Chess_单调DP


    简单的单调DP,连队列都用不到

    #include <cstdio>
    #include <vector>
    #include <algorithm>
    using namespace std;
    struct node
    {
        int s,p;
        bool operator<(const node &c) const
        {
            return p<c.p;
        }
    };
    vector<node>v[10005];
    node q;
    int f[10005],S[205];
    void work(int x)
    {
        if (!v[x].size())
        {
            f[x]=0;
            return ;
        }
        int i=0,n=0,now=0;
        while (i<v[x].size())
        {
            while (now<v[x].size() && v[x][now].s==v[x][i].s)
                ++now;
            if (!v[x][i].s)
            {
                S[n++]=now-i;
                if (now-i>=3)
                    S[n-1]*=2;
            }
            else
                S[n++]=i-now;
            i=now;
        }
        now=S[0];
        int ans=max(0,now);
        for (i=1; i<n; ++i)
        {
            now=max(now,0)+S[i];
            ans=max(ans,now);
        }
        f[x]=ans;
    }
    int main()
    {
        int T,i,n,m,t,s,p;
        scanf("%d",&T);
        for (int kcase=1; kcase<=T; ++kcase)
        {
            for (i=1; i<=10000; ++i)
                v[i].clear();
            scanf("%d%d",&n,&m);
            int maxt=0,ans=0;
            for (i=0; i<n; ++i)
            {
                scanf("%d%d%d",&t,&s,&p);
                maxt=max(maxt,t);
                q.s=s,q.p=p;
                v[t].push_back(q);
            }
            for (i=1; i<=maxt; ++i)
                sort(v[i].begin(),v[i].end());
            if (maxt<=m+1)
            {
                for (i=1; i<=maxt; ++i)
                    work(i),ans=max(ans,f[i]);
                printf("Case %d: %d\n",kcase,ans);
                continue;
            }
            for (i=1; i<=m; ++i)
                work(i),ans=max(ans,f[i]);
            int Q=0;
            for (; i<=maxt; ++i)
            {
                work(i);
                f[i]+=Q;
                ans=max(ans,f[i]);
                Q=max(Q,f[i-m]);
            }
    //        for (i=1; i<=maxt; ++i)
    //            printf("%d==========%d\n",i,f[i]);
            printf("Case %d: %d\n",kcase,ans);
        }
        return 0;
    }
    

      

  • 相关阅读:
    strlen和sizeof
    函数值传递和地址传递
    指向函数的指针变量
    for循环scanf赋值刷新缓冲区
    指针
    排序简化
    随机数找到最大值
    上楼梯问题
    分布式系统并发情况下会生成多个token
    Swagger 文档生成工具
  • 原文地址:https://www.cnblogs.com/Chierush/p/3120914.html
Copyright © 2020-2023  润新知