zoj3956(Course Selection System)_Solution

时间:2022-09-09 11:11:59

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

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

  1. ZOJ-3956 Course Selection System,01背包&excl;

    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背包&plus;思维

    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 &lbrack;01背包&rsqb;

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

  8. C&num;静态类和静态成员

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

  9. 关于Eclipse开发插件&lpar;三&rpar;

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

随机推荐

  1. Unity Cookie

    1   在Unity里面,选择脚本单击左键打开 Sync Mono Development  这样就可以打开整个工程的脚本文件 进而才能在脚本中继续进行切换      Mesh    MeshFilt ...

  2. 安装python的redis模块

    wget --no-check-certificate https://pypi.python.org/packages/source/r/redis/redis-2.8.0.tar.gz tar - ...

  3. 《深入理解Java虚拟机》学习笔记之内存回收

    垃圾收集(Garbage Collection,GC)并不是Java语言的半生产物,事实上GC历史远比Java久远,真正使用内存动态分配和垃圾收集技术的语言是诞生于1960年的Lisp语言.经过半个世 ...

  4. 将一个实体转换成 Url 参数的形式 &quest;a&equals;a&amp&semi;b&equals;b

    function toQueryString(obj) { var ret = []; for (var key in obj) { key = encodeURIComponent(key); va ...

  5. 使用数据库乐观锁解决高并发秒杀问题&comma;以及如何模拟高并发的场景&comma;CyclicBarrier和CountDownLatch类的用法

    数据库:mysql 数据库的乐观锁:一般通过数据表加version来实现,相对于悲观锁的话,更能省数据库性能,废话不多说,直接看代码 第一步: 建立数据库表: CREATE TABLE `skill_ ...

  6. &period;NET、C&num;和ASP&period;NET、ASP&period;NET MVC四者之间的区别

    什么是.NET? .NET是微软公司下的一个开发平台,.NET核心就是.NET Framwork(.NET框架)是.NET程序开发和运行的环境,在这个平台下可以用不同的语言进行开发,因为.NET是跨语 ...

  7. 在Ubuntu14&period;04上配置jdk环境

    服务器环境:Ubuntu14.04 server 1.进入oracle官网下载jdk1.7.0_71_x64.gz  重命名为jdk1.7 2.使用tar -xvf  jdk1.7.0_71_x64. ...

  8. 20175316 盛茂淞 2018-2019-2 《Java程序设计》实验二 面向对象程序设计 实验报告

    20175316 盛茂淞 2018-2019-2 <Java程序设计>实验二 面向对象程序设计 实验报告 (一)单元测试 在 IDEA中我们把产品代码放在src目录中,把测试代码放在tes ...

  9. Best Paper Awards in Computer Science 链接

    http://jeffhuang.com/best_paper_awards.html#icml

  10. ios7下UISearchBar UITextField 光标不出现的问题

    app支持ios7,在UINavBar 里面加入搜索框,结果光标一直出现不了.在overstackflow网站搜索了一下,竟然有人遇到相同的问题.... 解决办法如下: searchBar.tintC ...