Posterize
Pixels in a digital picture can be represented with three integers in the range 00 to 255255 that indicate the intensity of the red, green, and blue colors. To compress an image or to create an artistic effect, many photo-editing tools include a “posterize” operation which works as follows. Each color channel is examined separately; this problem focuses only on the red channel. Rather than allow all integers from 00 to 255255 for the red channel, a posterized image allows at most kk integers from this range. Each pixel’s original red intensity is replaced with the nearest of the allowed integers. The photo-editing tool selects a set of kk integers that minimizes the sum of the squared errors introduced across all pixels in the original image. If there are nn pixels that have original red values r1,…,rnr1,…,rn, and kk allowed integers v1,…,vkv1,…,vk, the sum of squared errors is defined as
Your task is to compute the minimum achievable sum of squared errors, given parameter kk and a description of the red intensities of an image’s pixels.
Input
The first line of the input contains two integers dd (1≤d≤2561≤d≤256), the number of distinct red values that occur in the original image, and kk (1≤k≤d1≤k≤d), the number of distinct red values allowed in the posterized image. The remaining dd lines indicate the number of pixels of the image having various red values. Each such line contains two integers rr (0≤r≤2550≤r≤255) and pp (1≤p≤2261≤p≤226), where rr is a red intensity value and pp is the number of pixels having red intensity rr. Those dd lines are given in increasing order of red value.
Output
Display the sum of the squared errors for an optimally chosen set of kk allowed integer values.
Sample Input 1 | Sample Output 1 |
---|---|
2 1 50 20000 150 10000 |
66670000 |
Sample Input 2 | Sample Output 2 |
---|---|
2 2 50 20000 150 10000 |
0 |
Sample Input 3 | Sample Output 3 |
---|---|
4 2 0 30000 25 30000 50 30000 255 30000 |
37500000 |
链接:
https://open.kattis.com/problems/posterize
题意:
给你一个长度为n个不同的数,记为ri,每个数有pi个,然后你还有一个大小为k的集合,每个数记为vj,求:
(公式的后面需要再*pi,自行脑补
题解:
dp,记忆化搜索+剪枝,题解在代码注释里面
代码:
31 const ll inf = 1e18; 32 ll n, k; 33 pair<ll, ll> p[MAXN]; 34 ll a[MAXN][MAXN]; 35 ll dp[MAXN][MAXN][MAXN];//dp[i][j][k]表示枚举到第i个数,用了j个数,当前的数为k的最小值 36 37 ll dfs(int pos, int cnt, int num) { 38 if (dp[pos][cnt][num] != inf) return dp[pos][cnt][num];//记忆化搜索 39 if (num < cnt - 1) return inf;//用了cnt个数的时候,当前的数最小应该是cnt-1 40 if (pos < cnt) return inf;//枚举到第pos个数的时候,最多只能有pos个不同的数 41 if (cnt == 0) return inf; 42 dp[pos][cnt][num] = min(dp[pos][cnt][num], dfs(pos - 1, cnt, num) + a[pos][num]); 43 rep(i, 0, num) dp[pos][cnt][num] = min(dp[pos][cnt][num], dfs(pos - 1, cnt - 1, i) + a[pos][num]); 44 return dp[pos][cnt][num]; 45 } 46 47 int main() { 48 ios::sync_with_stdio(false), cin.tie(0); 49 cin >> n >> k; 50 rep(i, 1, n + 1) cin >> p[i].first >> p[i].second; 51 sort(p + 1, p + 1 + n); 52 rep(i, 1, n + 1) rep(j, 0, 256) a[i][j] = (p[i].first - j)*(p[i].first - j)*p[i].second; 53 rep(i, 1, MAXN) rep(j, 0, MAXN) rep(k, 0, MAXN) dp[i][j][k] = inf; 54 ll ans = inf; 55 rep(i, 0, 256) ans = min(ans, dfs(n, k, i)); 56 cout << ans << endl; 57 return 0; 58 }