사용할 숫자의 개수를 "그룹의 개수"라 생각했다. 한 그룹에서 오차의 합이 최소가 되려면 그룹의 평균을 기준(양자화하는 숫자)으로 잡아야한다.
모듈화를 제대로 못해서 코딩이 계속 꼬였다. 다음부터는 함수로 적절히 쪼개서 문제를 푸는 데 방해되지 않도록 해야겠다.
#include <bits/stdc++.h> using namespace std; typedef long long lld; #define INF 987654321 int sum[105]; // 누적 합 int err[105][105]; // [a, b] 에서 나오는 오차 제곱의 합 int arr[105], n, s; int minError(int a, int b){ int psum = sum[b]-sum[a-1]; int aver = psum/(b-a+1.)+.5; int ret = 0; for(int i=a; i<=b; ++i) ret += (aver-arr[i])*(aver-arr[i]); return ret; } int dp[102][11]; int f(int pos, int rs /* 남은 개수 */){ if(pos > n) return 0; if(rs >= s) return INF; int& r = dp[pos][rs]; if(r != -1) return r; r = INF; for(int i=pos; i<=n; ++i){ r = min(r, err[pos][i] + f(i+1, rs+1)); } return r; } int main(){ int T; scanf("%d", &T); while(T--){ memset(dp, -1, sizeof(dp)); memset(sum, 0, sizeof(sum)); memset(err, 0, sizeof(err)); scanf("%d %d", &n, &s); for(int i=1; i<=n; ++i) scanf("%d", &arr[i]); sort(arr+1, arr+n+1); for(int i=1; i<=n; ++i){ sum[i] += sum[i-1] + arr[i]; } for(int i=1; i<=n; ++i){ for(int j=i; j<=n; ++j){ err[i][j] = minError(i, j); } } printf("%d\n", f(1, 0)); } return 0; }
댓글 없음:
댓글 쓰기