• 【解题报告】P1282 多米诺骨牌


    这是一道非常经典的动态规划题目······

    我们首先来对它来进行分析,我们首先发现他应该是用一个二维背包来解决的问题。

    二维背包第一个维度存储多米诺骨牌序号i,第二维度存储前i个多米诺骨牌第一行的权值,最后每个变量的值表示的是要操作的次数。

    于是动归方程式如下:

            if(j-x1[i]>=0) bag[i][j]=min(bag[i-1][j-x1[i]],bag[i][j]);
            if(j-x2[i]>=0) bag[i][j]=min(bag[i-1][j-x2[i]]+1,bag[i][j]);
    

    一定要记住必须反着写动态规划方程式,否则会GG,因为会出现重复相加的情况!!!谨记!!!!!!!!!!!

    下面这道题如果想到以上这些,这道题已经就AC了,下面上代码:

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    using namespace std;
    int bag[1006][6005];//分别记录前i个骨牌中第一行骨牌的和 
    int x1[1006], x2[1006];
    int main()
    {
        int n;
        int sum=0;
        scanf("%d",&n);
        for(int i=1;i<=n;++i)
        {
            scanf("%d%d",&x1[i],&x2[i]);
            sum+=x1[i]+x2[i];
        }
        memset(bag,0x7f7f7f7f7f,sizeof(bag)); 
        bag[1][x1[1]]=0;
        bag[1][x2[1]]=1;
        for(int i=1;i<=n;++i)
        {
            for(int j=1;j<=6*n;++j)
            {
                if(j-x1[i]>=0) bag[i][j]=min(bag[i-1][j-x1[i]],bag[i][j]);
                if(j-x2[i]>=0) bag[i][j]=min(bag[i-1][j-x2[i]]+1,bag[i][j]);
            }
        }
        int ans;
        if(sum%2==1)
        ans=sum/2+1;
        else ans=sum/2;
        while(bag[n][ans]==0x7f7f7f7f7f)
        ans--;
        printf("%d",bag[n][ans]);
        return 0;
    }
    
  • 相关阅读:
    C struct的内存对齐
    C++ 继承、函数重载
    C++ 操作符重载
    C中入栈顺序和运算顺序有关系吗?
    Java 关于finally、static
    C++ 类的复制控制
    Linux中vi的使用
    C++ 类的头文件、实现、使用
    (web)个人项目(挖宝网)
    MariaDB使用enum和set
  • 原文地址:https://www.cnblogs.com/mudrobot/p/13330918.html
Copyright © 2020-2023  润新知