zoukankan      html  css  js  c++  java
  • BZOJ1806: [Ioi2007]Miners 矿工配餐

    【传送门:BZOJ1806


    简要题意:

      有两个矿洞,有三种食物,给出n个食物的配送顺序,每个食物可以给任意一个矿洞,每个食物送到一个矿洞的收益是这个矿洞最近三次(包括送的那次)食物的种类数

      请你经过合理的分配食物使得收益最大


    题解:

      水题DP

      设f[i][t1][t2][t3][t4]为当前已经送了i个食物,且最近两次给第一个矿洞送了第t1和t2种食物(t1比t2更早送),给第二个矿洞送了第t3和t4种食物(t3比t4更早送)能得到的最大收益

      假如t1,t2,t3,t4为0,表示当前没有送那么多的餐

      转移想想就会了

      然后这题卡空间。。

      没关系,滚动数组一下就好了


    参考代码:

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    char st[110000];
    int f[2][4][4][4][4];
    int a[110000];
    int main()
    {
        int n;
        scanf("%d",&n);
        scanf("%s",st+1);
        for(int i=1;i<=n;i++)
        {
            if(st[i]=='M') a[i]=1;
            if(st[i]=='F') a[i]=2;
            if(st[i]=='B') a[i]=3;
        }
        memset(f,-1,sizeof(f));
        f[0][0][0][0][0]=0;
        int now=0,last=1;
        int ans=0;
        for(int i=1;i<=n;i++)
        {
            now^=1;last^=1;
            for(int t1=0;t1<=3;t1++)
            {
                for(int t2=0;t2<=3;t2++)
                {
                    int d1=0;
                    if(t1!=0&&t2==0)
                    {
                        d1=1;if(t1!=a[i]) d1=2;
                    }
                    else if(t1==0&&t2!=0)
                    {
                        d1=1;if(t2!=a[i]) d1=2;
                    }
                    else if(t1!=0&&t2!=0)
                    {
                        if(t1==t2)
                        {
                            d1=1;if(t1!=a[i]) d1=2;
                        }
                        else
                        {
                            d1=2;if(t1!=a[i]&&t2!=a[i]) d1=3;
                        }
                    }
                    else d1=1;
                    for(int t3=0;t3<=3;t3++)
                    {
                        for(int t4=0;t4<=3;t4++)
                        {
                            int d2=0;
                            if(t3!=0&&t4==0)
                            {
                                d2=1;if(t4!=a[i]) d2=2;
                            }
                            else if(t3==0&&t4!=0)
                            {
                                d2=1;if(t4!=a[i]) d2=2;
                            }
                            else if(t3!=0&&t4!=0)
                            {
                                if(t3==t4)
                                {
                                    d2=1;if(t3!=a[i]) d2=2;
                                }
                                else
                                {
                                    d2=2;if(t3!=a[i]&&t4!=a[i]) d2=3;
                                }
                            }
                            else d2=1;
                            if(f[last][t1][t2][t3][t4]!=-1)
                            {
                                f[now][t2][a[i]][t3][t4]=max(f[now][t2][a[i]][t3][t4],f[last][t1][t2][t3][t4]+d1);
                                f[now][t1][t2][t4][a[i]]=max(f[now][t1][t2][t4][a[i]],f[last][t1][t2][t3][t4]+d2);
                                ans=max(ans,max(f[now][t2][a[i]][t3][t4],f[now][t1][t2][t4][a[i]]));
                            }
                        }
                    }
                }
            }
        }
        printf("%d
    ",ans);
        return 0;
    }

     

  • 相关阅读:
    csharp:Validate email address using C#
    Sql:SQL Server CREATE SEQUENCE statement
    机器学习实战---SVD简化数据
    机器学习实战---PCA降维
    机器学习实战---使用FP-growth算法来高效发现频繁项集
    机器学习实战---使用Apriori算法进行关联分析
    机器学习实战---集成学习AdaBoost算法
    支持向量机核函数的实现
    支持向量机SMO算法实现(注释详细)
    帧缓冲
  • 原文地址:https://www.cnblogs.com/Never-mind/p/8883884.html
Copyright © 2011-2022 走看看