zoukankan      html  css  js  c++  java
  • P1282 多米诺骨牌 /// DP

    题目大意:

    https://www.luogu.org/problemnew/show/P1282

    题解

    当知道 总和 及 单行的和
    就可以算出差值的大小
    1 2 3 4(单行和l=10)
    8 7 6 5
    (总和s=36)
    则上下行的差值为 |l-(s-l)|

    #include <bits/stdc++.h>
    #define INF 0x3f3f3f3f
    using namespace std;
    int n,a[1005],b[1005],dp[1005][5005];
    /// dp[i][j]到第i块牌时 使单行和为j至少需要翻牌的次数
    int main()
    {
        while(~scanf("%d",&n)) {
            int s=0;
            for(int i=0;i<n;i++) {
                scanf("%d%d",&a[i],&b[i]);
                s+=a[i]+b[i]; /// 计算总和
            } // 因为牌上的数最大为6 最小为1 则差值的范围为 0到5
            memset(dp,INF,sizeof(dp));
            dp[0][b[0]]=1; dp[0][a[0]]=0;
            for(int i=1;i<n;i++)
                for(int j=0;j<=5*n;j++) { /// n块牌各种单行和的翻牌情况
                    if(j-a[i]>=0) dp[i][j]=min(dp[i][j],dp[i-1][j-a[i]]);
                    /// a[i]在上面 则从j-a[i]转移到j 不需要翻牌
                    if(j-b[i]>=0) dp[i][j]=min(dp[i][j],dp[i-1][j-b[i]]+1);
                    /// b[i]在下面 则从j-b[i]转移到j需要翻牌 应该+1
                }
    
            int minc=INF, mins=INF;
            for(int i=0;i<=5*n && i<=s;i++)
                if(dp[n-1][i]!=INF) { // 单行和为i的情况存在
                    if(fabs(i-(s-i))<mins) { // 这种情况得到的上下行差值更小
                        mins=fabs(i-(s-i)); 
                        minc=dp[n-1][i];
                    }
                    else if(fabs(i-(s-i))==mins)
                        minc=min(minc,dp[n-1][i]);
                }
    
            printf("%d
    ",minc);
        }
    
        return 0;
    }
    View Code
  • 相关阅读:
    HDOJ.1263
    另一种跳转actvity方式
    [转]Android中用Java获取时间实例
    获得当前时间的方法
    3d动画切换
    登录跳转效果
    activity 成popupwindow效果
    自定义preference的使用等等
    edittext输入框的背景效果
    自定义ListPreference
  • 原文地址:https://www.cnblogs.com/zquzjx/p/9327091.html
Copyright © 2011-2022 走看看