在文章开始时,先声明一下,小弟刚开始接触acm,水平有限,所以这里给出的程序是阉割版的,只实现了关键功能,无法ac
这道题类似于经典的数组分割问题,可参见《编程之美》2.18
#include <stdio.h>
#include <memory.h>
const int MAX_N = 202;
const int MAX_M = 22;
const int MAX_SUM = 1001;
bool dp[MAX_N][MAX_SUM];
int path[MAX_N][MAX_SUM];
bool is_neg[MAX_N][MAX_SUM];
int pcs[MAX_N];
int dfs[MAX_N];
int min2(int a, int b){
return a < b ? a : b;
}
void solve(int n, int m)
{
int i, j, k;
int base = m*20;
dp[0][base] = true;
for (k = 1; k <= n; ++k){
for (i = min2(k,m); i >= 1; --i){
for (j = 0; j <= 2*base; ++j){
int val = dfs[k-1] - pcs[k-1];
if (j >= val && j - val <= 2*base && dp[i-1][j-val]){
dp[i][j] = true;
path[i][j] = k;
}
}
}
}
i = m;
j = base;
while (j <= 2*base && !dp[i][j]){
j++;
}
k = base - 1;
while (k >= 0 && !dp[i][k]){
k--;
}
printf("%d %d\n", j-base, k-base);
k=j;
while (i >= 1){
printf("%d\n", path[i][k]);
k -= (dfs[path[i][k]-1] - pcs[path[i][k]-1]);
i--;
}
}
void input()
{
int n, m;
while (scanf("%d %d", &n, &m) && n != 0 && m != 0){
int i;
for (i = 0; i < n; ++i){
scanf("%d %d", &pcs[i], &dfs[i]);
}
memset(dp, 0, sizeof(dp));
solve(n, m);
}
}
int main()
{
input();
return 0;
}