• [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;
    }
     
  • 相关阅读:
    Python 爬虫-正则表达式
    Python 爬虫-信息的标记xml,json,yaml
    Python 爬虫-BeautifulSoup
    bzoj 1491
    bzoj 1406 数论
    Codeforces Round #496 (Div. 3) E2
    2017-2018 ACM-ICPC Northern Eurasia (Northeastern European Regional) Contest (NEERC 17) 日常训练
    Codeforces Round #496 (Div. 3) F
    bzoj 1415 期望dp + 记忆化搜索
    bzoj 1483 链表 + 启发式合并
  • 原文地址:https://www.cnblogs.com/wzx-RS-STHN/p/13539108.html
Copyright © 2020-2023  润新知