P1298(矩阵切割)DP

题目:

给你一个矩阵,其边长均为整数。你想把矩阵切割成总数最少的正方形,其边长也为整数。切割工作由一台切割机器完成,它能沿平行于矩形任一边的方向,从一边开始一直切割到另一边。对得到的矩形再分别进行切割。
输入数据:
输入文件中包含两个正整数,代表矩形的边长,每边长均在1—100之间。
输出数据:
输出文件包含一行,显示出你的程序得到的最理想的正方形数目。
输入输出示例:
CUTS.IN:
5 6
CUTS.OUT:
5

这道题呢可以用DFS+记忆化搜索,因为正在学习DP,所以就用DP写了

所以就用一个数组f[i][j]表示边长为i,j的矩形可以分出最少的正方形

所以就可知if(i==j)  f[i][j]=1;      所以就可以知道状态转移方程为:f[i][j]=min{f[i][k1]+f[i][j-k1],f[k2][j]+f[i-k2][j]}

(这里面f[i][k1]+f[i][j-k1]表示将矩形横着切开以后分成的两块包含的最少的矩形,同理可得f[k2][j]+f[i-k2][j]是竖着切开后两块的最少矩形) 1<=k1<j; 1<=k2<i;

代码如下:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
int f[2100][2100];
int a[2100][2100];
int main()
{
    int n,m;
    cin>>n>>m;
    memset(f,10,sizeof(f));
    f[0][0]=0;
    memset(a,0,sizeof(a));
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            a[i][j]=1;
            if(i==j)
                f[i][j]=1;
        }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            /*if(i==j)
                f[i][j]=1;*/
            int k1,k2;
            for(int k=1;k<j;k++)//横着切
            {
                k1=f[i][k]+f[i][j-k];
                if(k1<f[i][j])
                    f[i][j]=k1;
            }
            for(int k=1;k<i;k++)//竖着切
            {
                k2=f[k][j]+f[i-k][j];
                if(k2<f[i][j])
                    f[i][j]=k2;
            }
        }
    }
    /*for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            cout<<f[i][j]<<‘ ‘;
        }
        cout<<endl;
    }*/
    cout<<f[n][m]<<endl;
    return 0;
}

时间: 2024-11-08 16:57:58

P1298(矩阵切割)DP的相关文章

bzoj 3120 矩阵优化DP

我的第一道需要程序建矩阵的矩阵优化DP. 题目可以将不同的p分开处理. 对于p==0 || p==1 直接是0或1 对于p>1,就要DP了.这里以p==3为例: 设dp[i][s1][s2][r]为前i列,结尾为0的有s1行(0表示女生,1表示男生),结尾为01的有s2个,结尾为011的有n-s1-s2个,有r列全是1的方案数. 状态这么复杂,看起来一点也不能用矩阵优化,但我们可以将状态(s1,s2,r)hash成整数,然后建立状态之间的转移. 收获: 这种m超过10^7的一般都要用矩阵优化,如

矩阵乘法&amp;&amp;dp加速矩阵的思路(E. Wet Shark and Blocks)

There are b blocks of digits. Each one consisting of the same n digits, which are given to you in the input. Wet Shark must choose exactly one digit from each block and concatenate all of those digits together to form one large integer. For example,

Codeforces Round #341 (Div. 2) E. Wet Shark and Blocks(矩阵优化DP)

题目链接:点击打开链接 题意:给n个数作为一个块,有b个块,从其中若干个中选择数,每个块只能选一个数,最后组成一个数模x等于k的方法数. 思路:很容易想到这样一个DP方程 : 用dp[i][j]表示现在i位,余数是j.那么dp[i + 1][(j * 10 + k) % x] = dp[i][j] * cnt[k],k是指枚举放1~9中哪一位. 因为b特别大,显然要矩阵优化,知道了DP方程,其实矩阵的构造特别简单. 根据矩阵相乘的规则, 其实这个矩阵就是A[j][(j*10+a[k])%x]++

[矩阵乘法][DP]Vijos1067 Warcraft III 守望者的烦恼

题目梗概 n个单位的路程,主角每次最多可以走k个单位(也就是每次可以走1-k个单位),问最后到第n个监狱的方法数. 思考 DP转移方程并不难推导: dp[i]表示第i个监狱的方法数 $dp\left [ i \right ] = dp\left [ i-1 \right ] + dp\left [ i-2 \right ]\cdots \cdots + dp\left [ i-k-1 \right ]$ 但是这个n有点太大了,所以我们需要对DP方程进行优化. 仔细观察转移方程会发现,每次都是加上

【BZOJ4870】组合数问题 [矩阵乘法][DP]

组合数问题 Time Limit: 10 Sec  Memory Limit: 512 MB[Submit][Status][Discuss] Description Input 第一行有四个整数 n, p, k, r,所有整数含义见问题描述. Output 一行一个整数代表答案. Sample Input 2 10007 2 0 Sample Output 8 HINT 1 ≤ n ≤ 10^9, 0 ≤ r < k ≤ 50, 2 ≤ p ≤ 2^30 − 1 Solution 首先,不难发

poj3744高速功率矩阵+可能性DP

Scout YYF I Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4410   Accepted: 1151 Description YYF is a couragous scout. Now he is on a dangerous mission which is to penetrate into the enemy's base. After overcoming a series difficulties,

JZYZOJ 1542 [haoi2015]str 矩阵乘法 dp

http://172.20.6.3/Problem_Show.asp?id=1542 dp+矩阵乘法思路hin好想,对于我这种题目稍微学术就几乎什么也不会的人来说唯一的难点在于读题,因为一心想着划水题目没有看清楚,样例wa了一会最后仔细读题发现自己g的操作看错了,非常智障了 代码 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #inclu

[ZJOI2011]细胞——斐波那契数列+矩阵加速+dp

Description bzoj2323 Solution 题目看起来非常复杂. 本质不同的细胞这个条件显然太啰嗦, 是否有些可以挖掘的性质? 1.发现,只要第一次分裂不同,那么互相之间一定是不同的(即使总数目相同). 所以先考虑第一次分裂后,一个固定小球体数量的情况: 2.第一次分裂后,最后的小球体数量固定.想要方案数不同,必须连接方式不同. 可以列出dp式子,f[n](以n结尾砍一刀)=f[n-2]+f[n-3]+...+f[2]+f[0],而f[0]=1,f[1]=0 而fibo[n]-1

Codeforces 351C Jeff and Brackets 矩阵优化DP

题意:你要在纸上画一个长度为n * m的括号序列,第i个位置画左括号的花费是a[i % n], 画右括号的花费是b[i % n],问画完这个括号序列的最小花费.n <= 20, m <= 1e7 思路:如果不管n和m的限制,这个题很好做,设dp[i][j]是到i位置,平衡因子是j的花费,dp[i][j] = min(dp[i - 1][j - 1] + a[i], dp[i - 1][j + 1] + b[i]),但是这样n * m到2e8级别,这是我们无法承受的.不过,我们可以发现一个性质: