• 洛谷 P1282 多米诺骨牌("01"背包)


    传送门

    https://www.cnblogs.com/violet-acmer/p/9852294.html

    参考资料:

      [1]:https://blog.csdn.net/Darost/article/details/52517823

    题解:

      对于一个牌,无非就是翻转或者不翻转这两种情况,所以由此我们可以从决策入手

      设dp[i][j]为前i个骨牌差值为j的最小翻牌次数

      初始值全部赋值为INF;

      然后f[1][a[1]-b[1]]=0, f[1][b[1]-a[i]]=1;对应于第一张牌不翻和翻

      状态转移方程:

      f[i][j] = min(f[i-1][j-(a[i]-b[i])], f[i-1][j-(b[i]-a[i])]+1)]分别对应于不翻和翻

      由于有负数,要加上一个较大的中间数把所有的值转为正数,然后找答案在dp[n]里找,从较大的中间数开始双向查找,最早找到的就是答案。

    学习笔记:

      此题难点在于状态转移方程的查找。 

      dp[ ][ ]的作用很巧妙,是我不曾想到的,初始思路只知道一个暴力,就是枚举所有的可能,从中查找最优解,时间复杂度高达O(2^n),指定不能高效求解。

      算法之路还很长,一步一步来吧

    AC代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 using namespace std;
     5 #define mem(a,b) memset(a,b,sizeof(a))
     6 #define INF 0x3f3f3f3f
     7 const int maxn=1000+50;
     8 
     9 int n;
    10 int a[maxn],b[maxn];
    11 int dp[maxn][10*maxn];
    12 int mid=5000;//中间数
    13 
    14 void Solve()
    15 {
    16     dp[1][a[1]-b[1]+mid]=0,dp[1][b[1]-a[1]+mid]=1;
    17     for(int i=2;i <= n;++i)
    18     {
    19         for(int j=-5*n;j <= 5*n;++j)//查找dp[i][-5n,....,5n]的最优解
    20         {
    21             dp[i][j+mid]=min(dp[i][j+mid],dp[i-1][j-(a[i]-b[i])+mid]);
    22             dp[i][j+mid]=min(dp[i][j+mid],dp[i-1][j-(b[i]-a[i])+mid]+1);
    23         }
    24     }
    25     for(int i=mid,j=mid;i <= 5*mid || j >= 0;++i,--j)
    26         if(dp[n][i] != INF)
    27         {
    28             printf("%d
    ",dp[n][i]);
    29             break;
    30         }
    31         else if(dp[n][j] != INF)
    32         {
    33             printf("%d
    ",dp[n][j]);
    34             break;
    35         }
    36 
    37 }
    38 int main()
    39 {
    40     scanf("%d",&n);
    41     for(int i=1;i <= n;++i)
    42         scanf("%d%d",a+i,b+i);
    43     mem(dp,INF);
    44     Solve();
    45 }
    View Code
  • 相关阅读:
    electron中使用vue.js
    大三上学期学期总结
    小程序 弹窗的提示文字中添加链接
    03月14日总结
    03月16日总结
    03月10日总结
    03月11日总结
    03月19日总结
    03月17日总结
    03月15日总结
  • 原文地址:https://www.cnblogs.com/violet-acmer/p/9879834.html
Copyright © 2020-2023  润新知