��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; }