zoukankan      html  css  js  c++  java
  • [SHOI2001]化工厂装箱员(dp?暴力:暴力)

    ��118号工厂是世界唯一秘密提炼锎的化工厂,由于提炼锎的难度非常高,技术不是十分完善,所以工厂生产的锎成品可能会有3种不同的纯度,A:100%,B:1%,C:0.01%,为了出售方便,必须把不同纯度的成品分开装箱,装箱员grant第1次顺序从流水线上取10个成品(如果一共不足10个,则全部取出),以后每一次把手中某种纯度的成品放进相应的箱子,然后再从流水线上顺序取一些成品,使手中保持10个成品(如果把剩下的全部取出不足10个,则全部取出),如果所有的成品都装进了箱子,那么grant的任务就完成了。

    ��由于装箱是件非常累的事情,grant希望他能够以最少的装箱次数来完成他的任务,现在他请你编个程序帮助他。

    Solution

    写的像个dp似的,感觉其实就是个暴力(考场这么写肯定是打暴力

    设dp[i][j][k][l]表示拿到了i个,A有j个,B有j个,C有k个。

    大力转移。

    注意特判n<10的情况。

    Code

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    int dp[102][11][11][11],sum[3][104],a[102],n;
    inline void mi(int &a,int b){if(b<a)a=b;}
    char s[2];
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;++i){
            scanf("%s",s);
            a[i]=s[0]-'A';
            sum[a[i]][i]=sum[a[i]][i-1]+1;
            for(int j=0;j<=2;++j)if(j!=a[i])sum[j][i]=sum[j][i-1];
        }
        memset(dp,0x3f,sizeof(dp));
        if(n<10){
            cout<<(sum[0][n]!=0)+(sum[1][n]!=0)+(sum[2][n]!=0)<<endl;
            return 0;
        }
        dp[10][sum[0][10]][sum[1][10]][sum[2][10]]=0;
        for(int i=10;i<=n;++i)
          for(int j=0;j<=10;++j)
            for(int k=0;k<=10&&k+j<=10;++k)
              for(int l=0;l<=10&&k+j+l<=10;++l)if(dp[i][j][k][l]!=0x3f3f3f3f){
                   if(j){
                       int num=j;
                     mi(dp[min(i+num,n)][sum[0][min(n,i+num)]-sum[0][i]][k+sum[1][min(i+num,n)]-sum[1][i]][l+sum[2][min(i+num,n)]-sum[2][i]],dp[i][j][k][l]+1);
                 }
                if(k){
                    int num=k;
                    mi(dp[min(i+num,n)][j+sum[0][min(n,i+num)]-sum[0][i]][sum[1][min(n,i+num)]-sum[1][i]][l+sum[2][min(n,i+num)]-sum[2][i]],dp[i][j][k][l]+1);
                }
                if(l){
                    int num=l;
                    mi(dp[min(i+num,n)][j+sum[0][min(i+num,n)]-sum[0][i]][k+sum[1][min(i+num,n)]-sum[1][i]][sum[2][min(i+num,n)]-sum[2][i]],dp[i][j][k][l]+1);
                }
              }
            int ans=0x3f3f3f3f;
        for(int i=0;i<=10;++i)
          for(int j=0;i+j<=10;++j)
            for(int k=0;i+j+k<=10;++k)if(dp[n][i][j][k]!=0x3f3f3f3f)
              ans=min(ans,dp[n][i][j][k]+(i!=0)+(j!=0)+(k!=0));
        cout<<ans;;
        return 0;
    }
  • 相关阅读:
    春节不回家
    夜间突然发烧,无法入眠
    歌词写得真好
    近日看到网上许多BBS寻找SAP及ABAP程序的学习资料,本人深知学习的艰辛与不易,特贡献自己多年的学习资料,完全免费
    人生的真谛
    SMARTFORMS的调用方法(作者:曹玉平)
    自己给自己当医生
    将ocx添加到.NET
    AQtime + ocx/dll
    ActiveX:创建安装:
  • 原文地址:https://www.cnblogs.com/ZH-comld/p/9657522.html
Copyright © 2011-2022 走看看