hihocoder [Offer收割]编程练习赛18 C 最美和弦(dp)
Posted Gealo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hihocoder [Offer收割]编程练习赛18 C 最美和弦(dp)相关的知识,希望对你有一定的参考价值。
题目链接: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)的主要内容,如果未能解决你的问题,请参考以下文章
hihocoder offer收割编程练习赛12 C 矩形分割