69 条题解
-
0fengyi LV 9 @ 2008-07-19 15:30:29
还要用int64...郁闷
刁难的地方真不少 -
02008-07-16 19:51:20@
编译通过...
├ 测试数据 01:答案正确... 0ms
├ 测试数据 02:答案正确... 0ms
├ 测试数据 03:答案正确... 0ms
├ 测试数据 04:答案正确... 0ms
├ 测试数据 05:答案正确... 0ms
├ 测试数据 06:答案正确... 0ms
├ 测试数据 07:答案正确... 0ms
├ 测试数据 08:答案正确... 0ms
├ 测试数据 09:答案正确... 0ms
├ 测试数据 10:答案正确... 0ms
├ 测试数据 11:答案正确... 0ms
├ 测试数据 12:答案正确... 0ms
├ 测试数据 13:答案正确... 0ms
├ 测试数据 14:答案正确... 0ms
---|---|---|---|---|---|---|---|-
Accepted 有效得分:100 有效耗时:0ms令人火大的dp。。 注意精度问题。。
-
02008-07-16 18:45:34@
基本DP。。
第一次精度不够,竟然要用double才过>. -
02008-07-16 16:05:16@
编译通过...
├ 测试数据 01:答案正确... 0ms
├ 测试数据 02:答案正确... 0ms
├ 测试数据 03:答案正确... 0ms
├ 测试数据 04:答案正确... 0ms
├ 测试数据 05:答案正确... 0ms
├ 测试数据 06:答案正确... 0ms
├ 测试数据 07:答案正确... 0ms
├ 测试数据 08:答案正确... 0ms
├ 测试数据 09:答案正确... 0ms
├ 测试数据 10:答案正确... 0ms
├ 测试数据 11:答案正确... 0ms
├ 测试数据 12:答案正确... 0ms
├ 测试数据 13:答案正确... 0ms
├ 测试数据 14:答案正确... 0ms
---|---|---|---|---|---|---|---|-
Accepted 有效得分:100 有效耗时:0ms -
02008-07-15 18:13:55@
谢谢楼下呀
INT64就过第8个点了 -
02008-07-15 16:42:52@
int64就可以AC了
-
-12020-11-09 10:35:16@
/* 题目已知按顺序分组,dp[i] 表示前i辆车的最优方案 考虑第i辆车可以与前面相邻k辆车同时过桥分别分析k = (1 ~ i - k + 1)得出最小值就是dp[i]的最优解 dp[i] = min(dp[i], dp[j - 1] + a[j, i]) a[j, i]表示第j至i辆车同时过桥的时间花费(可预处理计算) */ #include <algorithm> //车队过桥问题 #include <cstring> #include <iostream> using namespace std; const int maxn = 1002; int Max, N; double Len; int w[maxn], v[maxn]; double dp[maxn]; int minv[maxn * 4]; //线段树, 区间最小值 // 复习线段树 void build(int s, int t, int p) { //对区间[s, t]建立线段树当前根编号为p if (s == t) { minv[p] = v[s]; return; } int m = (s + t) / 2; build(s, m, p * 2), build(m + 1, t, p * 2 + 1); minv[p] = min(minv[p * 2], minv[p * 2 + 1]); } int check(int l, int r, int s, int t, int p) { //查询区间[l, r]的线段树 if (l <= s && t <= r) return minv[p]; int m = (s + t) / 2; //二分是分树, 而不是分查找区间 if (r <= m) { return check(l, r, s, m, p * 2); } else if (m < l) { return check(l, r, m + 1, t, p * 2 + 1); } else { return min(check(l, m, s, m, p * 2), check(m + 1, r, m + 1, t, p * 2 + 1)); } } int main() { cin >> Max >> Len >> N; for (int i = 1; i <= N; i++) cin >> w[i] >> v[i]; memset(minv, 0x3f, sizeof(minv)); build(1, N, 1); memset(dp, 0x7f, sizeof(dp)); dp[0] = 0; dp[1] = Len / v[1]; for (int i = 2; i <= N; i++) { for (int j = i; j >= 1; j--) { //把区间[j, i]当做一个小队 long long tot = 0; for (int k = j; k <= i; k++) tot += w[k]; //计算区间[j, i]的重量 if (tot > Max) break; //如果超重, 以i为最后的计算完毕 dp[i] = min(dp[i], dp[j - 1] + Len / check(j, i, 1, N, 1)); } } printf("%.1f\n", dp[N] * 60); return 0; }
-
-12017-04-15 10:53:25@
弱弱的DP
```c++
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define maxn 2147483640
using namespace std;int l,n,g;
int w[1005],s[1005];
double f[1005];double mn(double a,double b){return a>b?b:a;}
double time(int a,int b){
int t=999999999;
for(int i=a;i<=b;i++)t=min(t,s[i]);
//cout<<a<<' '<<b<<' '<<t<<endl;
return (double)l/t;
}int main(){
int i,j,k;
scanf("%d%d%d",&g,&l,&n);
for(i=1;i<=n;i++)scanf("%d%d",&w[i],&s[i]);f[0]=0,f[1]=(double)l/s[1];
//cout<<f[1]<<endl;double tot;
for(i=2;i<=n;i++){
f[i]=999999999;
for(j=i;j>=1;j--){
tot=0;
for(k=j;k<=i;k++)tot=tot+w[k];
if(tot>g)break;
f[i]=mn(f[i],f[j-1]+time(j,i));
}
}printf("%.1f",f[n]*60);
return 0;
}
``` -
-12009-10-30 21:30:49@
不是太难,和P1331很像。我没看见“按顺序”,做了好半天,看了题解才明白。
要认真读题,要记得结果要*60,要找最小的V。。。