洛谷P2530 [SHOI2001]化工厂装箱员

题目描述

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

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

输入输出格式

输入格式:

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

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

输出格式:

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

输入输出样例

输入样例#1:
11
A
B
C
A
B
C
A
B
C
A
B
输出样例#1:
3

题解:
dp[i][a][b][c]为取了i次,A剩a个,B剩b个,C剩c个。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int z[120],dp[120][12][12][12];
int n,inf;

int dfs(int p,int a,int b,int c){
    if(p==n){
        dp[n][a][b][c]=(a>0)+(b>0)+(c>0);
        return dp[p][a][b][c];
    }
    for(;a+b+c<10;){
        p++;
        if(z[p]==1)a++;
        if(z[p]==2)b++;
        if(z[p]==3)c++;
        if(p==n)break;
    }
    if(dp[p][a][b][c]!=inf)return dp[p][a][b][c];
    if(a)dp[p][a][b][c]=min(dp[p][a][b][c],dfs(p,0,b,c)+1);
    if(b)dp[p][a][b][c]=min(dp[p][a][b][c],dfs(p,a,0,c)+1);
    if(c)dp[p][a][b][c]=min(dp[p][a][b][c],dfs(p,a,b,0)+1);
    return dp[p][a][b][c];
}

int main(){                                                                                                                  
    scanf("%d",&n);char ch;
    inf=0x3f3f3f3f;
    memset(dp,0x3f,sizeof(dp));
    for(int i=1;i<=n;i++){
        ch=getchar();
        while(ch<'A'||ch>'C')ch=getchar();
        int x=ch-'A'+1;
        z[i]=x;
    }
    printf("%d",dfs(0,0,0,0));
    return 0;
}

 

 
posted @ 2017-09-22 10:30  ANhour  阅读(296)  评论(0编辑  收藏  举报