首页 > 其他 > 详细

LG2530 「SHOI2001」化工厂装箱员 高维DP+记忆化搜索

时间:2019-09-21 22:51:02      阅读:132      评论:0      收藏:0      [点我收藏+]

问题描述

LG2530


题解

\(opt[i][a][b][c][d]\)代表装到第\(i\)个后,第\(1,2,3\)手上分别还剩\(a,b,c\)个的最小操作数。

记忆化搜索即可。

启示:如果状态没想法,可以先写爆搜,确定状态。


\(\mathrm{Code}\)

#include<bits/stdc++.h>
using namespace std;

void read(int &x){
    x=0;char ch=1;int fh;
    while(ch!='-'&&(ch>'9'||ch<'0')) ch=getchar();
    if(ch=='-') ch=getchar(),fh=-1;
    else fh=1;
    while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
    x*=fh;
}

const int maxn=100+7;
const int INF=0x3f3f3f3f;

int n,a[maxn];
int cnt[4];

int opt[maxn][11][11][11];
char c;

int dfs(int k[4],int step){
    if(opt[step][k[1]][k[2]][k[3]]) return opt[step][k[1]][k[2]][k[3]];
    if(!k[1]&&!k[2]&&!k[3]) return 0;
    int ret=INF;
    for(int i=1;i<=3;i++){
        if(!k[i]) continue;
        int aa=k[1],bb=k[2],cc=k[3],refe=k[i];
        k[i]=0;int j;
        for(j=step;j<=step+refe-1&&j<=n;j++) k[a[j]]++;
        ret=min(ret,dfs(k,j));
        k[1]=aa,k[2]=bb,k[3]=cc;
    }
    ++ret;
    return opt[step][k[1]][k[2]][k[3]]=ret;
}

int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>c;a[i]=c-'A'+1;
    }
    if(n<=10){
        int ans=0;
        for(int i=1;i<=n;i++) cnt[a[i]]++;
        for(int i=1;i<=3;i++) if(cnt[i]) ++ans;
        printf("%d\n",ans);return 0;
    }
    for(int i=1;i<=10;i++){
        cnt[a[i]]++;
    }
    printf("%d\n",dfs(cnt,11));
    return 0;
}

LG2530 「SHOI2001」化工厂装箱员 高维DP+记忆化搜索

原文:https://www.cnblogs.com/liubainian/p/11564557.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!