[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

题解:
水题哈,明显状态可以定义为f[i][j][k][g]为前i个,10个中A,B,C数量分别为j,k,g个
然后转移枚举清空哪一位再加上新产生的即可.
另外 这题还卡输入....
 1 #include <algorithm>
 2 #include <iostream>
 3 #include <cstdlib>
 4 #include <cstring>
 5 #include <cstdio>
 6 #include <cmath>
 7 using namespace std;
 8 const int N=105;
 9 int s[N],f[N][12][12][12],sum[N][3];
10 void work()
11 {
12     int n;char ch;
13     scanf("%d",&n);
14     for(int i=1;i<=n;i++){
15         ch=getchar();
16         while(ch>'C'||ch<'A')ch=getchar();
17         s[i]=ch-'A';
18         for(int j=0;j<=2;j++)
19             sum[i][j]=sum[i-1][j]+(s[i]==j);
20     }
21     if(n<=10){
22         printf("%d\n",(sum[n][0]>0)+(sum[n][1]>0)+(sum[n][2]>0));
23         return ;
24     }
25     int nxt,k1,k2,k3,tmp,inf;
26     memset(f,127/3,sizeof(f));inf=f[0][0][0][0];
27     f[10][sum[10][0]][sum[10][1]][sum[10][2]]=0;
28     for(int i=10;i<n;i++){
29         for(int j=0;j<=10;j++)
30             for(int k=0;k<=10;k++)
31                 for(int g=0;g<=10;g++){
32                     tmp=f[i][j][k][g];
33                     if(tmp==inf)continue;
34                     if(j){
35                         nxt=min(i+j,n);k1=sum[nxt][0]-sum[i][0];
36                         k2=k+sum[nxt][1]-sum[i][1];k3=g+sum[nxt][2]-sum[i][2];
37                         if(tmp+1<f[nxt][k1][k2][k3])
38                             f[nxt][k1][k2][k3]=tmp+1;
39                     }
40                     if(k){
41                         nxt=min(i+k,n);k1=j+sum[nxt][0]-sum[i][0];
42                         k2=sum[nxt][1]-sum[i][1];k3=g+sum[nxt][2]-sum[i][2];
43                           if(tmp+1<f[nxt][k1][k2][k3])
44                              f[nxt][k1][k2][k3]=tmp+1;
45                     }
46                     if(g){
47                           nxt=min(i+g,n);k1=j+sum[nxt][0]-sum[i][0];
48                         k2=k+sum[nxt][1]-sum[i][1];k3=sum[nxt][2]-sum[i][2];
49                           if(tmp+1<f[nxt][k1][k2][k3])
50                              f[nxt][k1][k2][k3]=tmp+1;
51                     }
52                 }
53     }
54     int ans=inf;
55     for(int i=0;i<=10;i++){
56         for(int j=0;j<=10;j++)
57             for(int k=0;k<=10;k++){
58                 tmp=f[n][i][j][k]+(i!=0)+(j!=0)+(k!=0);
59                 if(tmp<ans)ans=tmp;
60             }
61     }
62     printf("%d\n",ans);
63 }
64 int main()
65 {
66     work();
67     return 0;
68 }

 

 
posted @ 2017-08-08 20:22  PIPIBoss  阅读(264)  评论(0编辑  收藏  举报