码迷,mamicode.com
首页 > 其他好文 > 详细

hihocoder [Offer收割]编程练习赛18 C 最美和弦(dp)

时间:2017-07-16 23:34:55      阅读:353      评论:0      收藏:0      [点我收藏+]

标签:get   基础   print   理解   ace   fine   iostream   href   个数   

题目链接:http://hihocoder.com/problemset/problem/1532

 

题解:一道基础的dp,设dp[i][j][k][l]表示处理到第几个数,当前是哪个和弦错了几次初始x值是多少。这里还要再辅助一个val[k]表示处理到当前情况只错了k次的最小值是多少因为改变的不止是和弦还有初始值,可以看一下代码理解一下。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#define inf 0X3f3f3f3f
using namespace std;
int a[1010][3] , ans[3][1010][410] , dp[1010][2][22][410] , val[22];
int getnum(int i , int num , int ext) {
    int ans = 0;
    ans = abs(a[i][0] - num) + abs(a[i][1] - num - 3 - ext) + abs(a[i][2] - num - 7);
    return ans;
}
int main() {
    int n , k;
    scanf("%d%d" , &n , &k);
    for(int i = 0 ; i < n ; i++) {
        for(int j = 0 ; j < 3 ; j++) scanf("%d" , &a[i][j]);
    }
    for(int j = 0 ; j < n ; j++) {
        for(int i = -200 ; i <= 200 ; i++) {
            for(int l = 0 ; l <= k ; l++) {
                dp[j][0][l][i + 200] = dp[max(j - 1 , 0)][0][l][i + 200] + getnum(j , i , 0);
                if(l) dp[j][0][l][i + 200] = min(val[l - 1] + getnum(j , i , 0) , dp[j][0][l][i + 200]);
                dp[j][1][l][i + 200] = dp[max(j - 1 , 0)][1][l][i + 200] + getnum(j , i , 1);
                if(l) dp[j][1][l][i + 200] = min(val[l - 1] + getnum(j , i , 1) , dp[j][1][l][i + 200]);
            }
        }
        memset(val , inf , sizeof(val));
        for(int i = -200 ; i <= 200 ; i++) {
            for(int l = 0 ; l <= k ; l++) {
                val[l] = min(val[l] , dp[j][0][l][i + 200]);
                val[l] = min(val[l] , dp[j][1][l][i + 200]);
            }
        }
    }
    printf("%d\n" , val[k]);
    return 0;
}

 

hihocoder [Offer收割]编程练习赛18 C 最美和弦(dp)

标签:get   基础   print   理解   ace   fine   iostream   href   个数   

原文地址:http://www.cnblogs.com/TnT2333333/p/7192240.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!