HDU-1171 Big Event in HDU

时间:2022-04-05 07:48:16

Big Event in HDU

Problem Description
Nowadays,
we all know that Computer College is the biggest department in HDU.
But, maybe you don't know that Computer College had ever been split into
Computer College and Software College in 2002.
The splitting is
absolutely a big event in HDU! At the same time, it is a trouble thing
too. All facilities must go halves. First, all facilities are assessed,
and two facilities are thought to be same if they have the same value.
It is assumed that there is N (0<N<1000) kinds of facilities
(different value, different kinds).
 
Input
Input
contains multiple test cases. Each test case starts with a number N (0
< N <= 50 -- the total number of different facilities). The next N
lines contain an integer V (0<V<=50 --value of facility) and an
integer M (0<M<=100 --corresponding number of the facilities)
each. You can assume that all V are different.
A test case starting with a negative integer terminates input and this test case is not to be processed.
 
Output
For
each case, print one line containing two integers A and B which denote
the value of Computer College and Software College will get
respectively. A and B should be as equal as possible. At the same time,
you should guarantee that A is not less than B.
 
Sample Input
2
10 1
20 1
3
10 1
20 2
30 1
-1
 
Sample Output
20 10
40 40
 
可能是自己的做题意识还不够,做的时候总是不能是最简思路。
然后昨天晚上和亮哥说的时候,他教给我一种方法,既然求得是尽可能将物品的价值平分,那就先dp一遍,然后在dp的结果里边找,是否存在能将物品的总价值平分的结果,如果存在这种情况,输出就OK。但是亮哥告诉我的在不能平分的情况下的方法是错的,好吧,我又去参考博客了。
因为要得到尽可能平分的情况,在认为物品的价值与物品占用空间相同的情况下,在dp过后哦,在总空间 二分之一 的大小时,dp[half]就是尽可能平分的情况。因为尽可能将一半填满嘛。
///先进行一遍dp过程,因为反正都要进行判断是否能够均分,
///dp过程不能在中间过程断开,要进行完才行 #include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; const int max_1 = + ;
const int max_2 = ;
int val[max_2];
int num[max_2];
int dp[max_1]; int main()
{
int n, ans; while(~scanf("%d", &n))
{
if(n <= )
break;
memset(dp, , sizeof(dp));
ans = ;
for(int i = ; i < n; i++)
{
scanf("%d %d", val+i, num+i);///物品所占的体积与其的价值等值
ans += val[i] * num[i];
} for(int i = ; i < n; i++)
{
int k = ;
while(k < num[i])
{
for(int j = max_1; j - val[i]*k >= ; j--)
dp[j] = max(dp[j], dp[j - k*val[i]] + k*val[i]);
num[i] -= k;
k *= ;
} for(int j = max_1; j - val[i]*num[i] >= ; j--)
{
dp[j] = max(dp[j], dp[j-val[i]*num[i]] + num[i]*val[i]);
}
} // printf("%d\n", dp[max_1]);
int half = ans / ; if(dp[half] < ans - dp[half])
{
printf("%d %d\n", ans - dp[half], dp[half]);
}
else
{
printf("%d %d\n", dp[half],ans - dp[half]);
}
}
return ;
}

参考:

 #include <cstdio>
#include <cstring>
#include <algorithm> using namespace std;
const int max_1 = + ;
const int max_2 = ;
int val[max_2];
int num[max_2];
int dp[max_1]; int main()
{
int n;
int ans, half;
while(~scanf("%d", &n))
{
if(n <= )
break; ans = ;
memset(dp, , sizeof(dp));
for(int i = ; i < n; i++)
{
scanf("%d %d", val+i, num+i);
ans += val[i] * num[i];
} half = ans / ;
for(int i = ; i < n; i++)
{
if(val[i] * num[i] >= half)
{
for(int j = val[i]; j <= half; j++)
{
dp[j] = max(dp[j], dp[j - val[i]] + val[i]);
}
//printf("%d\n", dp[half]);
}
else
{
int k = ;
while(k < num[i])
{
for(int j = half; j - k*val[i] >= ; j--)
{
dp[j] = max(dp[j], dp[j - k*val[i]] + k*val[i]);
}
num[i] -= k;
k *= ;
} for(int j = half; j - num[i]*val[i] >= ; j--)
{
dp[j] = max(dp[j], dp[j - num[i]*val[i]] + num[i]*val[i]);
}
} } if(dp[half] < ans - dp[half])
{
printf("%d %d\n", ans - dp[half], dp[half]);
}
else
{
printf("%d %d\n", dp[half],ans - dp[half]);
}
}
return ;
}