• CF #EDU R1 E


    最二的一次了~我开始以为是带有贪心的DP,谁知道想错了。后来才想明白,暴力二分+记忆化DP

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define LL long long
    using namespace std;
    const int INF=(1<<29);
    int dp[35][35][55];
    
    int dfs(int n,int m,int k){	
    ///	if(n>m) swap(n,m);
    	if(dp[n][m][k]!=-1){
    		return dp[n][m][k];
    	}
    	if(k>n*m){
    		dp[n][m][k]=INF;
    		return INF;
    	}
    	if(k==n*m){
    		dp[n][m][k]=0;
    		return 0;
    	}
    	
    	dp[n][m][k]=INF;
    	for(int i=1;i<=m/2;i++){
    		for(int j=0;j<=min(i*n,k);j++){
    			dp[n][m][k]=min(dp[n][m][k],dfs(n,i,j)+dfs(n,m-i,k-j)+n*n);
    		}
    	}
    	
    	for(int i=1;i<=n/2;i++){
    		for(int j=0;j<=min(i*m,k);j++){
    			dp[n][m][k]=min(dp[n][m][k],dfs(i,m,j)+dfs(n-i,m,k-j)+m*m);
    		}
    	}
    	
    	return dp[n][m][k];
    }
    
    
    int main(){
        int n,m,k;
        int T;
        scanf("%d",&T);
    	memset(dp,-1,sizeof(dp));
    	for(int i=0;i<=30;i++)
    		for(int j=0;j<=30;j++) dp[i][j][0]=0;
        while(T--){
            scanf("%d%d%d",&n,&m,&k);
       ///     ans=(1LL<<60);
    	///	if(n>m) swap(n,m);
    		if(dp[n][m][k]==-1)
    			dfs(n,m,k);
            cout<<dp[n][m][k]<<endl;
        }
        
        return 0;
    }
    

      

  • 相关阅读:
    hdu 2082 找单词
    hdu 2079 选课时间(题目已修改,注意读题)
    hdu 2073 无限的路
    hdu 2062 Subset sequence
    poj 2777 Count Color
    hdu 2067 小兔的棋盘
    卡特兰数
    poj3468
    hdu1394
    hdu1166(线段树之单点更新)
  • 原文地址:https://www.cnblogs.com/jie-dcai/p/4964453.html
Copyright © 2020-2023  润新知