dp
有w1就加
两个状态 能量1-100 w2 1-7 (2^7已近超过100了)
#include<iostream>
#include<iomanip>
#include<math.h>
using namespace std;
#define INF 99999999
#define MIN(a,b) (a>b?b:a)
double dp[2][105][15];
int mm[8];
void clear(int now)
{
for(int i=1;i<=100;i++)
for(int j=0;j<=7;j++)
dp[now][i][j]=INF;
}
double cal(int v,int p1,int p2,int t1,int t2)
{
if(v<p1)
return INF;
if(v>p2)
return t2;
return t1-(1.0*v-p1)/(p2-p1)*(t1-t2);
}
int main()
{
mm[0]=1;
for(int i=1;i<=7;i++)
mm[i]=mm[i-1]*2;
int n,p;
while(cin>>n>>p&&(n||p))
{
int now=0,last=1;
int p1,p2,t1,t2,w1,w2;
cin>>p1>>p2>>t1>>t2>>w1>>w2;
clear(now);
int u=p+w1;
if(u>100)
u=100;
dp[now][u][w2]=cal(p,p1,p2,t1,t2);
for(int i=2;i<=n;i++)
{
now^=1;
last^=1;
cin>>p1>>p2>>t1>>t2>>w1>>w2;
clear(now);
for(int j=1;j<=100;j++)
{
for(int k=0;k<=7;k++)
{
for(int l=0;l<=k;l++)
{
int u=w1+j*mm[l];
if(u>100)
u=100;
int v=w2+k-l;
if(v>7)
v=7;
double ret=cal(j*mm[l],p1,p2,t1,t2);
dp[now][u][v]=MIN(dp[now][u][v],dp[last][j][k]+ret);
}
}
}
}
double ans=INF;
for(int i=1;i<=100;i++)
for(int j=0;j<=7;j++)
ans=MIN(ans,dp[now][i][j]);
if(ans==INF)
cout<<"Impossible"<<endl;
else
cout<<fixed<<setprecision(2)<<ans<<endl;
}
return 0;
}
附组数据
input
10 1
1 100 100 1 1 1
1 100 100 1 1 1
1 100 100 1 1 1
1 100 100 1 1 1
1 100 100 1 1 1
1 100 100 1 1 1
1 100 100 1 1 1
1 100 100 1 1 1
1 100 100 1 1 1
output
406.00