题目大意:
要你输入n,代表学院里面有n种设备,并且在下面输入n行,每一行输入v,m代表设备的价格为v,设备的数量是m.然后要求把这些设备的总价值分摊,尽量平分,使其总价值接近相等,最好是相等。
解题思路:
一开始有点儿难转换为母函数,好像很多牛人都用DP做嘞,速度上应该更快吧。转换为母函数的思路是:把设备排列组合,把所有可能的组合都打出来,然后从总价值的中间开始搜,只要搜到第一个就是了,再用total-i就是最靠近的两个价值了。。所以输出是total-i,i。这就不用担心总价值是奇数了。写出母函数的生成函数就可以快速秒掉了。母函数用了1500MS,这样算慢吧。应该比DP要慢很多,但是题目给了5000MS的上限,哈~母函数还是挺伟大滴。
代码:
#include
#include
using namespace std;
const int MAX=55;
const int AMAX=250005;
typedef struct f
{
int val;
int c;
int sum;
}F;
int c1[AMAX],c2[AMAX];
int main(void)
{
F fa[MAX];
int n,i,j,k;
while(cin>>n)
{
if(n<0)
exit(0);
int tal=0;
memset(c1,0,sizeof(c1));
memset(c2,0,sizeof(c2));
for(i=1;i<=n;i++)
{
cin>>fa[i].val>>fa[i].c;
fa[i].sum=fa[i].val*fa[i].c;
tal+=fa[i].sum;
}
c1[0]=1;
for(i=fa[1].val;i<=fa[1].sum;i+=fa[1].val)
c1[i]=1;
for(i=2;i<=n;i++)
{
for(j=0;j<=tal;j++)
{
for(k=0 ; k+j<=tal && k<=fa[i].sum ; k+=fa[i].val)
{
c2[k+j]+=c1[j];
}
}
for(j=0;j<=tal;j++)
{
c1[j]=c2[j];
c2[j]=0;
}
}
// cout<=0;i--)//从中间开始搜,用tal-i,不用担心tal为奇数
{
if(c1[i]!=0)
{
cout<