• 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
  • 相关阅读:
    R语言大小写字母转换
    SparkR(R on Spark)编程指南 含 dataframe操作
    SparkR(R on Spark)编程指南 含 dataframe操作
    R-table和tapply函数
    r table
    多变量频率统计——r
    R语言-查看加载包、卸除加载包及安装包与卸载包
    flask 电子邮件进阶实践-用模板发送163邮件 --
    flask 电子邮件Flask-Mail --
    数据库进阶实践-事件监听 --
  • 原文地址:https://www.cnblogs.com/hxer/p/5185142.html
Copyright © 2020-2023  润新知