20 条题解
-
1j18tm01 LV 10 @ 2020-05-24 12:18:43
我终于过了QAQ
#include <cstdio> #include <cstring> #define N 21 int na,nb,n,ta[N],tb[N],ka[N],kb[N],tim[N][61][61],dp[N][61][61]; inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x*f; } inline int max(int x,int y){return x>y?x:y;} inline int min(int x,int y){return x<y?x:y;} inline void calc(int x){ int t[2][61][61];//0--A,1--B memset(t,0x3f,sizeof(t)); t[1][0][0]=t[0][0][0]=0; for(int i=0;i<=na;++i) for(int j=0;j<=nb;++j){ for(int k=1;k<=i;++k) t[0][i][j]=min(t[0][i][j],t[1][i-k][j]+ta[x]+ka[x]*k*k); for(int k=1;k<=j;++k) t[1][i][j]=min(t[1][i][j],t[0][i][j-k]+tb[x]+kb[x]*k*k); tim[x][i][j]=min(t[0][i][j],t[1][i][j]); } } int main(){ // freopen("a.in","r",stdin); na=read();nb=read();n=read(); for(int i=1;i<=n;++i) ta[i]=read(),tb[i]=read(),ka[i]=read(),kb[i]=read(); for(int i=1;i<=n;++i) calc(i); memset(dp,0x3f,sizeof(dp)); for(int i=0;i<=na;++i) for(int j=0;j<=nb;++j) dp[1][i][j]=tim[1][i][j]; for(int x=2;x<=n;++x) for(int i=0;i<=na;++i) for(int j=0;j<=nb;++j){ for(int ki=0;ki<=i;++ki) for(int kj=0;kj<=j;++kj) dp[x][i][j]=min(dp[x][i][j],max(dp[x-1][i-ki][j-kj],tim[x][ki][kj])); } printf("%d\n",dp[n][na][nb]); return 0; }
-
02009-10-07 17:26:43@
解法一
首先很容易想到DP两次
第1次 f1(k,i,j)表示 第K台机器,处理i个a任务,j个b任务的最小时间
第2次 背包(p*na^2*nb^2) 没有puppy的大力支持会超2个点
当然+上oimaster大牛的优化后可以解决这个问题
PS:这个优化我一直写不好(囧)
___|\__|\__|\__|\__|\__|\__|\__|_内有恶狗,切勿靠近___|\__|\__|\__|\__|\__|\__|\__|__
解法二
DP+2分答案(用1维背包判断可行性)
问题完美解决 -
02009-09-03 21:21:56@
编译通过...
├ 测试数据 01:答案正确... 0ms
├ 测试数据 02:答案正确... 0ms
├ 测试数据 03:答案正确... 0ms
├ 测试数据 04:答案正确... 0ms
├ 测试数据 05:答案正确... 0ms
├ 测试数据 06:答案正确... 0ms
---|---|---|---|---|---|---|---|-
Accepted 有效得分:100 有效耗时:0msvar i,j,n,m,p,k,q,x,y,mm,an:longint;
a,b:array[1..200,1..4]of longint;
g:array[0..20,0..200,0..200,1..2]of longint;
f:array[0..100]of longint;
d:array[1..20,0..100]of longint;
function min(o,s:longint):longint;
begin
if os then exit(o)else exit(s);
end;
procedure zhao(l,r:longint);
begin
if l=r then begin an:=l;exit;end;
for i:=1 to m do
f[i]:=-999;
f[0]:=0;
for i:=1 to p do
for j:=0 to m do
d:=-999;
x:=(l+r)div 2;
for i:=1 to p do
for j:=0 to m do
for k:=0 to n do
if g=0 then
f[j]:=max(f[j-k]+d,f[j]);
if f[m]>=n then begin zhao(l,x);exit;end
else begin zhao(x+1,r);exit;end;
end;
begin
read(m,n,p);
for i:=1 to p do
for j:=1 to 4 do
read(a);
fillchar(g,sizeof(g),$7F);
for i:=1 to p do
begin
g:=0;g:=0;
end;
for i:=1 to p do
for j:=0 to m do
for k:=0 to n do
begin
for q:=0 to j-1 do
g:=min(g+a*(j-q)*(j-q)+a,g);
for q:=0 to k-1 do
g:=min(g+a*(k-q)*(k-q)+a,g);
end;
for i:=1 to p do
for j:=0 to m do
for k:=0 to n do
g:=min(g,g);
mm:=99999999;
for i:=1 to p do if mm>g then mm:=g;
zhao(1,mm);
writeln(an);end.
用二分查找法解题
终于过了 AC率啊 -
02009-06-18 21:35:01@
编译通过...
├ 测试数据 01:答案正确... 0ms
├ 测试数据 02:答案正确... 0ms
├ 测试数据 03:答案正确... 0ms
├ 测试数据 04:答案正确... 0ms
├ 测试数据 05:答案正确... 56ms
├ 测试数据 06:答案正确... 41ms
---|---|---|---|---|---|---|---|-
Accepted 有效得分:100 有效耗时:97ms黑书上写得很深奥,我没看懂。觉得oimaster神牛的方法很简单有效。膜拜神牛!
-
02009-05-19 21:04:25@
编译通过...
├ 测试数据 01:答案正确... 0ms
├ 测试数据 02:答案正确... 0ms
├ 测试数据 03:答案正确... 0ms
├ 测试数据 04:答案正确... 0ms
├ 测试数据 05:答案正确... 25ms
├ 测试数据 06:答案正确... 9ms
---|---|---|---|---|---|---|---|-
Accepted 有效得分:100 有效耗时:34ms剪枝剪错。。。50->70->100。。。膜拜oimaster!!!
-
02009-05-14 18:36:49@
此题可以有
枚举当前点做多少工作
可以加个优化
如果枚举之前点做多少工作
那个优化的作用就体现不出了 -
02009-04-24 07:48:14@
饿
-
02009-04-21 22:15:52@
├ 测试数据 04:答案正确... 0ms
├ 测试数据 05:答案正确... 0ms
├ 测试数据 06:答案正确... 0ms
---|---|---|---|---|---|---|---|-
Accepted 有效得分:100 有效耗时:0mspuppy 就是 神奇 ……
明明 最坏 大概 会运算 2*10^8还多 , 结果 竟然……DP + 弱弱 的 类似 最优化 剪枝 ……
引用 黑书 上的: 先 枚举 决策 再 枚举 状态,容易 进行“剪枝”。
不过 那 上面 介绍的上下界 估计 看不懂 的说…… 于是 自己 随便找个,结果 貌似还不错 囧…… -
02009-04-19 21:08:13@
Accepted 有效得分:100 有效耗时:0ms
我个人认为楼下的楼下大牛说得很对,二分的确很快。
首先预处理是求出第i个计算机做x1个a类任务和x2个b类任务,方程很好写。
之后二分最差运行时间,每次计算前i台计算机在不超过上限时间的情况下
做x1个a类任务的同时能最多做多少个b类任务,剩下的就是输出了 -
02009-04-19 20:17:17@
做两次DP。
第一次求第i个计算机做x1个a类任务,x2个b类任务所需的组少时间g。
第二次求前i个计算机做x1个a类任务,x2个b类任务所需的组少时间f。
第二次DP的时间复杂度为O(p*na^2*nb^2),实测会超时,只要加一个小优化。
因为第二次DP是取最大值,并且很容易得到:
当x1'>=x1,x2'>=x2时,g>=g。
所以说如果第i个计算机处理的时间超过了前面i-1个计算机处理的时间,再让第i个计算机做更多的工作只会增加时间,可以剪枝。
这样的话:
编译通过...
├ 测试数据 01:答案正确... 0ms
├ 测试数据 02:答案正确... 0ms
├ 测试数据 03:答案正确... 0ms
├ 测试数据 04:答案正确... 0ms
├ 测试数据 05:答案正确... 41ms
├ 测试数据 06:答案正确... 56ms -
02009-04-17 08:03:06@
暴力DP
编译通过...
├ 测试数据 01:答案正确... 0ms
├ 测试数据 02:答案正确... 0ms
├ 测试数据 03:答案正确... 0ms
├ 测试数据 04:答案正确... 103ms
├ 测试数据 05:答案正确... 509ms
├ 测试数据 06:答案正确... 666ms
---|---|---|---|---|---|---|---|-
Accepted 有效得分:100 有效耗时:1278ms -
02009-04-16 19:08:47@
Accepted 有效得分:100 有效耗时:231ms
暴力DP,加个小剪枝就AC了 -
02009-04-17 22:09:11@
编译通过...
├ 测试数据 01:答案正确... 0ms
├ 测试数据 02:答案正确... 0ms
├ 测试数据 03:答案正确... 0ms
├ 测试数据 04:答案正确... 0ms
├ 测试数据 05:答案正确... 0ms
├ 测试数据 06:答案正确... 0ms
---|---|---|---|---|---|---|---|-
Accepted 有效得分:100 有效耗时:0ms想到了个新方法,貌似不错.
大家貌似是双重dp
我是用dp预处理然后二分答案 -
02009-04-16 14:02:36@
Accepted 有效得分:100 有效耗时:1263ms
庆祝AC 250 题!
DP,但一定要加剪枝! -
02009-04-15 22:55:18@
卡时,加剪枝,加RP,加puppy
-
02009-04-15 21:16:05@
线形双重DP。。。
-
02009-04-15 20:44:51@
啊
-
02009-04-15 20:24:10@
动态规划
参见黑书.
-
-12013-03-25 23:10:48@
试问大牛们如何A的那么完美,吾的code除了tle就是re,求解释
-
-12009-09-27 20:04:25@
二分的确快!!!!
- 1