zoukankan      html  css  js  c++  java
  • [SHOI2001]化工厂装箱员

    题目

    Description

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

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

    Input

    第1行为n(1<=n<=100),为成品的数量

    以后n行,每行为一个大写字母A,B或C,表示成品的纯度。

    Output

    仅一行,为grant需要的最少的装箱次数。

    Sample Input

    11
    A
    B
    C
    A
    B
    C
    A
    B
    C
    A
    B

    Sample Output

    3

    思路

    这是一道 $ dp$ 题;

    我们可以设 $dp[i][j][k][l]$ 表示当取到第 $i$个成品时,手里有$A,B,C$ 种成品各 $j~,k~,l$个;

    那么就有两种情况,取成品,和装箱;

    那么取走成品的转移方程是:

    $if(j& &s[i]=='A')$

        $dp[i][j][k][l]=min(dp[i][j][k][l],dp[i-1][j-1][k][l])$

    表示取走成品 $A$;

    那么装箱的转移方程就是:

    $dp[i][0][k][l]=min(dp[i][0][k][l],dp[i][j][k][l]+1)$

    表示把成品 $A$ 进行装箱,装箱的次数加$1$;

    这样就可以$AC$ 了;

    代码

    #include<bits/stdc++.h>
    #define re register
    typedef long long ll;using namespace std;
    inline ll read()
    {
        ll a=0,f=1; char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') c=getchar();}
        while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
        return a*f;
    }
    ll n;
    char s[101];
    ll dp[101][11][11][11];
    int main()
    {
        memset(dp,127/3,sizeof(dp));
        n=read();//读入
        for(re ll i=1;i<=n;i++)
            cin>>s[i];//读入
        dp[0][0][0][0]=0;//赋初值
        for(re ll i=1;i<=n;i++)
        for(re ll j=0;j<=10;j++)
        for(re ll k=0;k<=10;k++)
        for(re ll l=0;l<=10;l++)
        {
            if(j+k+l>10)
                continue;//题目中要求手上的成品不得超过10
            if(j&&s[i]=='A')  dp[i][j][k][l]=min(dp[i][j][k][l],dp[i-1][j-1][k][l]);
            if(k&&s[i]=='B')  dp[i][j][k][l]=min(dp[i][j][k][l],dp[i-1][j][k-1][l]);
            if(l&&s[i]=='C')  dp[i][j][k][l]=min(dp[i][j][k][l],dp[i-1][j][k][l-1]);
                //取成品的转移方程
            dp[i][0][k][l]=min(dp[i][0][k][l],dp[i][j][k][l]+1);
            dp[i][j][0][l]=min(dp[i][j][0][l],dp[i][j][k][l]+1);
            dp[i][j][k][0]=min(dp[i][j][k][0],dp[i][j][k][l]+1);
                //装箱
        }
        printf("%lld
    ",dp[n][0][0][0]);//输出
            //return 0;
    }
     
  • 相关阅读:
    系统设计的一些原则
    分层开发思想与小笼包
    工作与生活
    Microsoft .NET Pet Shop 4 架构与技术分析
    用人之道(二) 如何管理软件开发团队
    也谈很多开发人员的毛病
    《3S新闻周刊》第10期,本期策划:“超女”营销带来的启示
    浅析ArcIMS
    MapX的坐标问题
    应用ArcIMS构建GMap风格的地图应用
  • 原文地址:https://www.cnblogs.com/wzx-RS-STHN/p/13539108.html
Copyright © 2011-2022 走看看