zoj3956_Solution

H=sum(hi),C=sum(ci),Value=H*H-H*C-C*C

求Value的最大值

Solution:

动态规划:

共两维:H,C           固定一维C,在该维值C相同的情况下另一维应最大H,从而动态规划另一维H,转变为01背包问题。

优化:

H*H-H*C-C*C=0 (H,C>0)

H/C=(1+sqrt(5))/2=1.6180…

必会选择h/c>(1+sqrt(5))/2 的(h,c)对

证明:

若Value大于0,则H/C>(1+sqrt(5))/2,

若再加上h/c>(1+sqrt(5))/2 的(h,c)对,

(H+h)* (H+h)-(H+h) *(C+c)-(C+c)* (C+c)=H*H-H*C-C*C+h*h-h*c-c*c+2*H*h-H*c-h*C-2*C*c

[ (H+h)* (H+h)-(H+h) *(C+c)-(C+c)* (C+c) ] – [ H*H-H*C-C*C ]

= h*h-h*c-c*c+2*H*h-H*c-h*C-2*C*c

>2*H*h-H*c-h*C-2*C*c

>2*H*h - H*h*(1+sqrt(5))/2 - h*H*(1+sqrt(5))/2 – 2*H*(1+sqrt(5))/2*h*(1+sqrt(5))/2

=0

值必然会增大,所以必会选择h/c>(1+sqrt(5))/2 的(h,c)对,得证

所以可以把h/c>=(1+sqrt(5))/2的(h,c)对先选出来,再对h/c<(1+sqrt(5))/2的(h,c)对进行动态规划,然后在动态规划的基础上再加上h/c>=(1+sqrt(5))/2的(h,c)对求得在相同C的基础上H的最大值。

某个贪心的方法:按照h/c从大到小的顺序依次对h,c对进行排序,然后依次选取,直到值小于0。

证明不成立:

原来                 H,C                             value

加入                 h1,c1                         value1

再加入             h2,c2                         value2

(h1/c1>h2/c2)

若原来加入    h2,c2                         value3

证明有可能只加入h2,c2数值更大:

h1,c1数值非常大,且h1/c1<(1+sqrt(5))/2,加入h1,c1后value1<0,而再加入h2,c2后,value2<value1<0;而尽管h2/c2< h1/c1<(1+sqrt(5))/2,但加入h2,h2后,value2>value。

如H=1700,C=1000

h1=16000,c1=10000

h2=159,c1=100

value=190000

value1=-2410000

value2=-2501019

value3=200981

当有三个数据(1700,1000),(16000,10000),(159,100),则用此方法求得结果为190000,并不正确。所以该方法错误。

DP:

 #include <stdio.h>
#include <stdlib.h>
#define maxn 500 int main()
{
//500*100(total) *500(n) *10(test cases)=250000000 //max_result=(10000*500)^2
//the maximum of h[i] is larger than c[i],thus choose c
//the total of c is not larger than 500*100=50000
//when c is the same , we need maximum h
long h[maxn+],c[maxn+];
//<=10000/100*500
long t,n,i,j,k,ans[maxn+],f[];
long long s,result;
scanf("%ld",&t);
for (k=;k<=t;k++)
{
ans[]=;
result=;
scanf("%ld",&n);
for (i=;i<=n;i++)
{
scanf("%ld %ld",&h[i],&c[i]);
ans[i]=ans[i-]+c[i];
}
for (i=;i<=ans[n];i++)
f[i]=-;
f[]=;
for (i=;i<=n;i++)
//when choose course ith ,the maximum of credit is ans[i](including c[i])
for (j=ans[i];j>=c[i];j--)
if (f[j-c[i]]!=- && f[j-c[i]]+h[i]>f[j])
f[j]=f[j-c[i]]+h[i];
for (i=;i<=ans[n];i++)
if (f[i]!=-)
{
s=f[i]*f[i]-f[i]*i-i*i;
if (s>result)
result=s;
}
printf("%lld\n",result);
}
return ;
}
/*
100 1 1 1 1 1 1 1 1
0+101+102+……
not obvious WorstSituation
10 10 10 10 10
50+50+50+50+50=250
0+10+20+30+40=100
save halt of the time Previous:
49900*500=24950000
Current:
0+100+200+…+49900=12500000
10Cases
12500000*10=1,2500,0000
*/

DP(advance):

 #include <stdio.h>
#include <stdlib.h>
#define maxn 500 //原来60s,现在20s int main()
{
//500*100(total) *500(n) *10(test cases)=250000000 //max_result=(10000*500)^2
//the maximum of h[i] is larger than c[i],thus choose c
//the total of c is not larger than 500*100=50000
//when c is the same , we need maximum h
long h[maxn+],c[maxn+],ans[maxn+],f[];
//<=10000/100*500
long t,n,i,j,k,g,temp,hh,cc;
long long s,result;
double line=(1.0+sqrt(5.0))/;
scanf("%ld",&t);
for (k=;k<=t;k++)
{
ans[]=;
scanf("%ld",&n);
for (i=;i<=n;i++)
scanf("%ld %ld",&h[i],&c[i]);
g=n+;
for (i=n;i>=;i--)
if (1.0*h[i]/c[i]>=line)
{
g--;
temp=h[i];
h[i]=h[g];
h[g]=temp;
temp=c[i];
c[i]=c[g];
c[g]=temp;
}
g--;
//a[g+1]~a[n] h[i]/c[i]>=line must be chose
hh=;
cc=;
for (i=g+;i<=n;i++)
{
hh+=h[i];
cc+=c[i];
}
//a[1]~a[g] h[i]/c[i]<line
for (i=;i<=g;i++)
ans[i]=ans[i-]+c[i];
for (i=;i<=ans[g];i++)
f[i]=-;
f[]=;
for (i=;i<=g;i++)
//when choose course ith ,the maximum of credit is ans[i](including c[i])
for (j=ans[i];j>=c[i];j--)
if (f[j-c[i]]!=- && f[j-c[i]]+h[i]>f[j])
f[j]=f[j-c[i]]+h[i];
result=hh*hh-hh*cc-cc*cc;
for (i=;i<=ans[g];i++)
if (f[i]!=-)
{
s=(f[i]+hh)*(f[i]+hh)-(f[i]+hh)*(i+cc)-(i+cc)*(i+cc);
if (s>result)
result=s;
}
printf("%lld\n",result);
}
return ;
}
/*
100 1 1 1 1 1 1 1 1
0+101+102+……
not obvious WorstSituation
10 10 10 10 10
50+50+50+50+50=250
0+10+20+30+40=100
save halt of the time Previous:
49900*500=24950000
Current:
0+100+200+…+49900=12500000
10Cases
12500000*10=1,2500,0000
*/

贪心(Wrong):

 #include <stdio.h>
#include <stdlib.h>
#define maxn 500 struct node
{
long h,c;
double per;
}; int cmp(const void *a,const void *b)
{
if ((*(struct node *)b).per>(*(struct node *)a).per)
return ;
else
return ;
} long long max(long long a,long long b)
{
if (a>b)
return a;
else
return b;
} int main()
{
long t,k,l,n,ht,ct;
long long maxs;
struct node course[maxn+];
scanf("%ld",&t);
for (k=;k<=t;k++)
{
scanf("%ld",&n);
for (l=;l<n;l++)
{
scanf("%ld%ld",&course[l].h,&course[l].c);
course[l].per=1.0*course[l].h/course[l].c;
}
qsort(course,n,sizeof(struct node),cmp);
ht=;
ct=;
maxs=;
for (l=;l<n;l++)
{
ht+=course[l].h;
ct+=course[l].c;
maxs=max(maxs,ht*ht-ht*ct-ct*ct);
}
printf("%lld\n",maxs);
}
return ;
}
/*
5
1 4
2 5
6 3
7 2
4 4
*/

最普通的方法,保证正确,用于测试其它程序是否正确:

 #include <stdio.h>
#include <stdlib.h> struct node
{
long h,c;
double per;
};
long n;
long long maxs=;
struct node course[]; int cmp(const void *a,const void *b)
{
return (*(struct node *)b).per-(*(struct node *)a).per;
} long long max(long long a,long long b)
{
if (a>b)
return a;
else
return b;
} void dfs(long d,long ht,long ct)
{
if (d==n)
return ;
if (ct!=)
maxs=max(maxs,ht*ht-ht*ct-ct*ct);
dfs(d+,ht+course[d].h,ct+course[d].c);
dfs(d+,ht,ct);
} int main()
{
long t,k,l;
scanf("%ld",&t);
for (k=;k<=t;k++)
{
scanf("%ld",&n);
maxs=;
for (l=;l<n;l++)
{
scanf("%ld%ld",&course[l].h,&course[l].c);
course[l].per=1.0*course[l].h/course[l].c;
}
dfs(,,);
printf("%lld\n",maxs);
}
return ;
}

以下是我做的关于此题做的评测方法,值得一览

http://pan.baidu.com/s/1c1WeUGS

zoj3956(Course Selection System)_Solution的更多相关文章

  1. ZOJ-3956 Course Selection System,01背包!

    Course Selection System 比赛的时候最后20分钟想到了是01背包,奈何没时间推出怎么背. 题意:n门课程,每门课程都有一个h值和c值,现在给出一个happy的定义,所选的课程的h ...

  2. ZOJ Course Selection System DP

    http://acm.zju.edu.cn/onlinejudge/showContestProblem.do?problemId=5565 Course Selection System Time ...

  3. Course Selection System ZOJ - 3956 01背包+思维

    Course Selection System ZOJ - 3956 这个题目居然是一个01背包,我觉得好难想啊,根本就没有想到. 这个题目把题目给的转化为  ans = a*a-a*b-b*b 这个 ...

  4. ZOJ 3956 Course Selection System 背包DP

    ZOJ3956 观察数据范围, c的值非常小 只有100 所以c的和也很有限 只有50000 是否可以从这里下手? 对于某一个c的和 我们一定希望h的和最大 才有可能是最终答案. 于是有了类似背包的d ...

  5. ZOJ 3956 Course Selection System

    题意 有n节课可供选择,每节课都有两个值Hi和Ci,如果学生选择了m节课(x1,x2,....,xm),则它的舒适值被定义为: //这里没有公式((lll¬ω¬)),因为那个图片我保存不下来≧ ﹏ ≦ ...

  6. ZOJ - 3956 Course Selection System 【01背包变形】

    题目链接 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3956 题意 给出N组Hi Ci 然后 要选出若干个 使得 这个式 ...

  7. ZOJ 3956 Course Selection System [01背包]

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3956 题意:就是给你Hi,Ci的值,问怎么取使得下面那个式子的值最大: 理 ...

  8. C#静态类和静态成员

    1. 静态类 1.1 简介  静态类和类成员用于创建无需创建类的实例就能够访问的数据和函数. 静态类成员可用于分离独立于任何对象标识的数据和行为:无论对象发生什么更改,这些数据和函数都不会随之变化. ...

  9. 关于Eclipse开发插件(三)

    视图之间实现事件监听 两个视图中的组件之间的互动,在开发插件的时候是经常碰到的问题.点击视图1列表的某项时,视图2的文本框显示相应的字符. 第一种主动式: 主动式就是在视图1的代码块中获取对视图2的对 ...

随机推荐

  1. Linux服务器性能压力测试

    对于新采购的服务器,需要进行有必要的性能测试.这里选择UnixBench工具进行性能测试.记录如下: 1)安装使用下面的脚本使用了最新版UnixBench5.1.3来测试,注释了关于graphic的测 ...

  2. Jenkins部署Python项目实战

    一.背景 我们工作中常用Jenkins部署Java代码,因其灵活的插件特性,例如jdk,maven,ant等使得java项目编译后上线部署一气呵成,同样对于脚本语言类型如Python上线部署,利用Je ...

  3. 微信扫描 安卓和ios 不会

    wx.ready(function(){ $('#scan').click(function(){ wx.scanQRCode({ needResult: 1, // 默认为0,扫描结果由微信处理,1 ...

  4. jeecg中vaildfrom的复杂的表单校验

    简介 jeecg生成的页面都是使用validfrom组件来确保数据的完整性和准确性. 凡要验证格式的元素均需绑定datatype属性,datatype可选值内置有10类,用来指定不同的验证格式. 如果 ...

  5. github链接

    github链接:https://github.com/bjing123     test1:https://github.com/bjing123/test-/blob/master/test1.t ...

  6. Python学习笔记(一)——初学Python

    1.Python环境配置 本人配置Python2.7及Python3.6版本 将Python3.6环境配置在线,因此默认为Python3.6版本 Python2.7及Python3.6共存 2.简单操 ...

  7. Failed to execute goal org.springframework.boot

    报错 [ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:1.4.0.RELEASE:ru ...

  8. Apache Shiro Session Management

    https://shiro.apache.org/session-management.html#session-management https://shiro.apache.org/session ...

  9. Jfrog Artifactory jenkins 流水线使用docker的方式培训[暂未成功]

    1. 创建jenkins的流水线 2. 创建artifactory的镜像仓库 3. 创建generic的仓库上传需要的 war包还有tar包. 4. 修改pipeline的 脚本 主要修改的地方. 修 ...

  10. Visual Studio 2017 激活密钥 [复制记录]

    Visual Studio 2017(VS2017) 企业版 Enterprise 注册码:NJVYC-BMHX2-G77MM-4XJMR-6Q8QF Visual Studio 2017(VS201 ...