一开始看错题了,以为书是任意排列的,结果怎么样也搞不出状态方程……后来看了题解才发现顺序是固定的,这样这题就成水题了……
状态转移方程为:dp[cur]=min{dp[i]+max{h[j]|cur<=j<i}|cur<i<n}
为了避免精度问题,可以把浮点数转化为整数来做就行了。
#include <iostream>
#include <fstream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
#define M 1010
int n,W;
int h[M],w[M];
char str[M];
int dp[M];
int dfs(int cur)
{
if(dp[cur]!=-1) return dp[cur];
if(cur==n) return dp[cur]=0;
int &ans=dp[cur];
ans=1<<30;
int mh=0,sum=0;
for(int i=cur;i<n;i++)
{
sum+=w[i];
mh=max(mh,h[i]);
if(sum>W) break;
ans=min(ans,dfs(i+1)+mh);
}
return ans;
}
int main()
{
freopen("in.txt","r",stdin);
while(gets(str)!=NULL&&str[0]!='0')
{
int a,b;
sscanf(str,"%d %d.%d",&n,&a,&b);
W=10000*a+b;
for(int i=0;i<n;i++)
{
gets(str);
int a1,b1,a2,b2;
sscanf(str,"%d.%d %d.%d",&a1,&b1,&a2,&b2);
h[i]=10000*a1+b1;
w[i]=10000*a2+b2;
}
memset(dp,-1,sizeof(dp));
printf("%.4f\n",(double)dfs(0)/10000);
}
return 0;
}