zoukankan      html  css  js  c++  java
  • Codeforces Problem 598E

    Chocolate Bar

    题意: 有一个n*m(1<= n,m<=30)的矩形巧克力,每次能横向或者是纵向切,且每次切的花费为所切边长的平方,问你最后得到k个单位巧克力( k <= min(n*m,50) )的最小花费是多少?

    思路: 数据规模不大,但是贪心不能得到最优解,很自然想到了dp;里面涉及到行的减少和列的减少,在dp[][]表示中必定要以行数和列数作为dp的含义,但是好像这还不够,如果单单只是一个二维的dp[][]那这个表示的是取了(或者还需)几个单位巧克力呢?
    ==>三维dp[n][m][k]:当还剩下n行m列还需要取k个单位巧克力时的最小花费;
    转移式就是对每个”可切”的行||列遍历,取最小的花费;注意将n,m分开后,还要对之后各自所要得到的巧克力的数量进行划分,即对k进行遍历(从0开始);即dp数组作为记忆,否则直接dfs会TLE.

    #include<bits/stdc++.h>
    using namespace std;
    #define rep(i,n) for(int i = 0;i < (n);i++)
    #define inf 0x3f3f3f3f
    int dp[33][33][55];
    int dfs(int n,int m,int k)
    {
        if(k <= 0||n * m == k)return 0;
        int &ret = dp[n][m][k];
        if(ret) return ret;
        else ret = inf;
        for(int i = 1;i < n;i++){
            for(int j = 0;j <= k;j++)
            ret = min(ret, dfs(i,m,j) + dfs(n-i,m,k - j) + m*m);
        }
        for(int i = 1;i < m;i++){
            for(int j = 0;j <= k;j++)
                ret = min(ret, dfs(n,i,j) + dfs(n,m-i,k - j) + n*n);
        }
        return ret;
    }
    int main()
    {
        int T,n,m,k;
        cin>>T;
        while(T--){
            scanf("%d%d%d",&n,&m,&k);
            printf("%d
    ",dfs(n,m,k));
        }
    }
    View Code
  • 相关阅读:
    hdu5360 Hiking(水题)
    hdu5348 MZL's endless loop(欧拉回路)
    hdu5351 MZL's Border(规律题,java)
    hdu5347 MZL's chemistry(打表)
    hdu5344 MZL's xor(水题)
    hdu5338 ZZX and Permutations(贪心、线段树)
    hdu 5325 Crazy Bobo (树形dp)
    hdu5323 Solve this interesting problem(爆搜)
    hdu5322 Hope(dp)
    Lightoj1009 Back to Underworld(带权并查集)
  • 原文地址:https://www.cnblogs.com/hxer/p/5185142.html
Copyright © 2011-2022 走看看