zoukankan      html  css  js  c++  java
  • LG2530 「SHOI2001」化工厂装箱员 高维DP+记忆化搜索

    问题描述

    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
    ",ans);return 0;
    	}
    	for(int i=1;i<=10;i++){
    		cnt[a[i]]++;
    	}
    	printf("%d
    ",dfs(cnt,11));
    	return 0;
    }
    
  • 相关阅读:
    栈和堆的区别【个人总结】
    理解堆与栈
    javacript属性
    Reapeater CommandName ,CommandArgument
    FormsAuthentication.HashPasswordForStoringInConfigFile(str1, str2);
    文件上传处理
    GetJson
    js内置对象
    Debug
    [转]关于一些SPFA的标程
  • 原文地址:https://www.cnblogs.com/liubainian/p/11564557.html
Copyright © 2011-2022 走看看