20 条题解
-
3PowderHan LV 10 @ 2017-05-08 09:06:14
/* 两种做法 Orz反正我不会 第一 建棵树直接模拟即可,每次找花费最小的位置插入,结果是正确的 第二 动态规划 f[i][j]表示i个物品,使用j个指针的最小费用 f[i][j]=min{f[j-1]+g[t][j]} g[i][j]表示当前指针为j,使用了i个物品 g[i][j]=min{f[i][l]+p[j]*i*i) 初值f[1][1],g[1][x] 做到i时给f[1]赋值 于是复杂度就是O(n^2*k) */ #include <iostream> #include <cstdio> #include <cstdlib> #include <memory.h> #include <algorithm> using namespace std; int n,k,p[200],f[2000][200]; void init() { memset(f,0,sizeof(f)); memset(p,0,sizeof(p)); scanf("%d%d",&n,&k); for (int i = 1; i <= k; ++ i) scanf("%d",&p[i]); sort(p+1,p+1+k); } int mmin(int a,int b) { if (a == 0) return b; else return min(a,b); } int dp(int x,int y,int l) { if (x == 1) { f[x][y] = p[y]; return f[x][y]; } if (y == k) { f[x][y] = p[y] * x * x + dp(x,1,x-1); return f[x][y]; } int temp; temp = k - y + 1; if (temp * l < x) return 0xFFFFFFF; if (f[x][y] != 0) return f[x][y]; temp = (x-1) / (temp) + 1; for (int i = temp; i <= l; ++ i) { if (i == 1) f[x][y] = dp(x-1,y+1,x-2) + p[y]; else f[x][y] = mmin( f[x][y] , dp(x-i,y+1,x-i-1) + dp(i,1,i-1) + i * i * p[y] ); } return f[x][y]; } int main() { init(); printf("%d",dp(n,1,n-1)); return 0; }
-
12017-01-27 20:50:41@
#include <cstdio> #include <algorithm> #include <limits> #define maxint (numeric_limits<int>::max)()/8 using namespace std; int n,m,a[151],f[1001][151]; bool cmp1(int a,int b) { return a<b; } int dfs1(int x,int y,int l) { if (x==1) { f[x][y]=a[y]; return f[x][y]; } if (y==m) { f[x][y]=a[y]*x*x+dfs1(x,1,x-1); return f[x][y]; } if ((m-y+1)*l<x) return maxint; if (f[x][y]!=maxint) return f[x][y]; for (int i=(x-1)/(m-y+1)+1;i<=l;i++) { if (i==1) f[x][y]=dfs1(x-1,y+1,x-2)+a[y]; else f[x][y]=min(f[x][y],dfs1(x-i,y+1,x-i-1)+dfs1(i,1,i-1)+i*i*a[y]); } return f[x][y]; } int main() { scanf("%d%d",&n,&m); for (int i=1;i<=m;i++) scanf("%d",&a[i]); sort(a+1,a+m+1,cmp1); for (int i=0;i<=n;i++) for (int j=0;j<=m;j++) f[i][j]=maxint; printf("%d\n",dfs1(n,1,n-1)); }
-
12008-12-13 00:29:26@
好久没有切题了- -||
f[i][j]表示i个物品,使用j个指针的最小费用
f[i][j]=min{f[j-1]+g[t][j]}
g[i][j]表示当前指针为j,使用了i个物品
g[i][j]=min{f[i][l]+p[j]*i*i)初值f[1][1],g[1][x]
做到i时给f[1]赋值
于是复杂度就是O(n^2*k) -
02015-05-06 22:23:53@
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<memory.h>
#include<algorithm>
using namespace std;int n,k,p[200],f[2000][200];
void init()
{
memset(f,0,sizeof(f));
memset(p,0,sizeof(p));
scanf("%d%d",&n,&k);
for (int i = 1; i <= k; ++ i)
scanf("%d",&p[i]);
sort(p+1,p+1+k);
}int mmin(int a,int b)
{
if (a == 0)
return b;
else
return min(a,b);
}int dp(int x,int y,int l)
{
if (x == 1)
{
f[x][y] = p[y];
return f[x][y];
}
if (y == k)
{
f[x][y] = p[y] * x * x + dp(x,1,x-1);
return f[x][y];
}
int temp;
temp = k - y + 1;
if (temp * l < x)
return 0xFFFFFFF;
if (f[x][y] != 0)
return f[x][y];
temp = (x-1) / (temp) + 1;
for (int i = temp; i <= l; ++ i)
{
if (i == 1)
f[x][y] = dp(x-1,y+1,x-2) + p[y];
else
f[x][y] = mmin( f[x][y] , dp(x-i,y+1,x-i-1) + dp(i,1,i-1) + i * i * p[y] );
}
return f[x][y];
}int main()
{
init();
printf("%d",dp(n,1,n-1));
return 0;
} -
02014-02-28 09:45:04@
卧槽,啥坑爹题目= =,lazycal更本看不懂嘛╮(╯▽╰)╭
-
02013-07-06 19:53:57@
方程f[i,j]表示有i个文件,这i个文件在某个等级的子目录中,只能往 第j个指针即之后添加数(意思就是,1..j-1这几个指针都占用了)
优化:我们可以把指针大小从小到大排序下,越小的显然要加越多的文件。
不过加了这个优化也仅仅把10724 ms 优化到4246 ms~上海红茶馆 - Windows Server 2003 via JudgeDaemon2/13.7.4.0 via libjudge
编译成功测试数据 #0: Accepted, time = 1312 ms, mem = 1256 KiB, score = 10
测试数据 #1: Accepted, time = 0 ms, mem = 1232 KiB, score = 10
测试数据 #2: Accepted, time = 14 ms, mem = 1232 KiB, score = 10
测试数据 #3: Accepted, time = 136 ms, mem = 1240 KiB, score = 10
测试数据 #4: Accepted, time = 906 ms, mem = 1256 KiB, score = 10
测试数据 #5: Accepted, time = 1312 ms, mem = 1256 KiB, score = 10
测试数据 #6: Accepted, time = 2218 ms, mem = 1256 KiB, score = 10
测试数据 #7: Accepted, time = 1312 ms, mem = 1256 KiB, score = 10
测试数据 #8: Accepted, time = 1296 ms, mem = 1256 KiB, score = 10
测试数据 #9: Accepted, time = 2218 ms, mem = 1256 KiB, score = 10
Accepted, time = 10724 ms, mem = 1256 KiB, score = 100
上海红茶馆 - Windows Server 2012 via JudgeDaemon2/13.7.4.0 via libjudge
编译成功测试数据 #0: Accepted, time = 625 ms, mem = 1372 KiB, score = 10
测试数据 #1: Accepted, time = 0 ms, mem = 1372 KiB, score = 10
测试数据 #2: Accepted, time = 0 ms, mem = 1372 KiB, score = 10
测试数据 #3: Accepted, time = 46 ms, mem = 1372 KiB, score = 10
测试数据 #4: Accepted, time = 437 ms, mem = 1372 KiB, score = 10
测试数据 #5: Accepted, time = 609 ms, mem = 1372 KiB, score = 10
测试数据 #6: Accepted, time = 609 ms, mem = 1372 KiB, score = 10
测试数据 #7: Accepted, time = 671 ms, mem = 1372 KiB, score = 10
测试数据 #8: Accepted, time = 640 ms, mem = 1376 KiB, score = 10
测试数据 #9: Accepted, time = 609 ms, mem = 1372 KiB, score = 10
Accepted, time = 4246 ms, mem = 1376 KiB, score = 100var
f:array[0..1001,0..151]of longint;
i,j,k,m,n,p:Longint;
a:array[0..151]of longint;
procedure init;
beginread(n,k);
for i:=1 to k do
read(a[i]);
for i:=1 to k do
for j:=i+1 to k do
if a[i]>a[j] then
begin
p:=a[i];a[i]:=a[j];a[j]:=p;
end;
end;
function min(a,b:Longint):Longint;
beginif (a>b)or(a=0) then exit(b);
exit(a);
end;
function dp(x,y,l:Longint):Longint;
var
i,j,p,mm,num:Longint;
begin
if x=1 then
begin
f[x,y]:=a[y];
exit(f[x,y]);
end;
if y=k then
begin
f[x,y]:=a[y]*x*x+dp(x,1,x-1);
exit(f[x,y]);
end;num:=k-y+1;
if num*l<x then exit(maxlongint shr 2);if f[x,y]<>0 then exit(f[x,y]);
mm:=(x-1)div (k-y+1) +1;
for i:=mm to l do
begin
if i=1 then
f[x,y]:=dp(x-1,y+1,x-2)+a[y]
else
f[x,y]:=min(f[x,y],dp(x-i,y+1,x-i-1)+dp(i,1,i-1)+i*i*a[y]);
end;
exit(f[x,y]);
end;
begin
init;writeln(dp(n,1,n-1));
end. -
02010-07-04 10:22:27@
这题最恶心的就是边界条件,DP方程很简单。
-
02009-11-09 18:17:46@
模拟果然可以..
只是代码比DP长点 -
02009-10-25 13:32:36@
编译通过...
├ 测试数据 01:答案正确... 775ms
├ 测试数据 02:答案正确... 0ms
├ 测试数据 03:答案正确... 0ms
├ 测试数据 04:答案正确... 0ms
├ 测试数据 05:答案正确... 416ms
├ 测试数据 06:答案正确... 744ms
├ 测试数据 07:答案正确... 869ms
├ 测试数据 08:答案正确... 791ms
├ 测试数据 09:答案正确... 759ms
├ 测试数据 10:答案正确... 759ms
---|---|---|---|---|---|---|---|-
Accepted 有效得分:100 有效耗时:5113ms
貌似DP很慢的说
不过时限12秒......连1s都没破
第40个...... -
02009-10-09 18:23:33@
编译通过...
├ 测试数据 01:答案正确... 0ms
├ 测试数据 02:答案正确... 0ms
├ 测试数据 03:答案正确... 0ms
├ 测试数据 04:答案正确... 0ms
├ 测试数据 05:答案正确... 0ms
├ 测试数据 06:答案正确... 0ms
├ 测试数据 07:答案正确... 0ms
├ 测试数据 08:答案正确... 0ms
├ 测试数据 09:答案正确... 0ms
├ 测试数据 10:答案正确... 0ms
---|---|---|---|---|---|---|---|-
Accepted 有效得分:100 有效耗时:0ms此题模拟才是王道,
时间O(N^2)
空间O(N)!!!!! -
02009-10-09 15:58:41@
编译通过...
├ 测试数据 01:答案正确... 947ms
├ 测试数据 02:答案正确... 0ms
├ 测试数据 03:答案正确... 0ms
├ 测试数据 04:答案正确... 0ms
├ 测试数据 05:答案正确... 603ms
├ 测试数据 06:答案正确... 962ms
├ 测试数据 07:答案正确... 947ms
├ 测试数据 08:答案正确... 947ms
├ 测试数据 09:答案正确... 931ms
├ 测试数据 10:答案正确... 947ms
---|---|---|---|---|---|---|---|-
Accepted 有效得分:100 有效耗时:6284ms -
02009-08-05 16:25:28@
时间限制 Time Limitation
12S
........... -
02009-07-09 21:49:29@
├ 测试数据 01:答案正确... 869ms
├ 测试数据 02:答案正确... 0ms
├ 测试数据 03:答案正确... 0ms
├ 测试数据 04:答案正确... 0ms
├ 测试数据 05:答案正确... 525ms
├ 测试数据 06:答案正确... 853ms
├ 测试数据 07:答案正确... 838ms
├ 测试数据 08:答案正确... 869ms
├ 测试数据 09:答案正确... 869ms
├ 测试数据 10:答案正确... 853ms居然全在1s内,puppy好强大!
题解(实际有的地方我自己还是不太明白)
-
02009-03-31 20:18:48@
看了stelan 女王的 ,我AC了,成为第 16 个!
-
02008-10-13 22:29:19@
作者有才,打那么多
-
02007-12-14 09:11:59@
江苏2007省选第一轮居然直接拿这道题考我们。。。
建棵树直接模拟即可,每次找花费最小的位置插入,结果是正确的(我也不能证明)
当场做没想到动态规划,就这么模拟过了。。。 -
02007-07-26 19:10:28@
大牛们 加油!
快做出呀!! -
02006-11-16 20:46:43@
楼下的好帅啊~~~^-^
用DP方程的时候一定想清楚,每个量是由哪些量来推导的
还有就是要剪枝哦,不然的话单个数据都可能达到5000多ms -
02006-10-19 20:36:13@
总结:认真写DP方程,注意细节
P.S. 此题为湖南省选拔考HNOI2002 Day1 Problem2
P.P.S. 终于呆在Rank 1了,感觉好棒啊~.~
-
-12009-07-01 12:04:32@
这么简单的题我都懒着去做,vijos的前途啊!!!
- 1