题意:给出N只牛,每只牛有E份能量,要牛群在尽可能短的时间内跑完D米路程。
牛的能量的消耗规则如下:
牛群以X米/分钟的速度前进,领头的牛会消耗X^2份/分钟的能量,其余的消耗X份/分钟,领头的牛可以在每分钟更换,如果某一头牛剩余能量不支持他以该速度跑完整1分钟,那么他就会掉队,只要有1头牛到达终点都算完成。
喜闻乐见的DP,推一下就可以发现,某一头牛以某一个速度作为领头时候,跟它在什么时候作为领头牛没关系。如果一头牛没有当过领头牛,那么他所消耗的能量跟所跑的路程是相等的。
DP[ i ][ j ][ k ]代表前i - 1头牛已经处理完的第i头牛消耗了k份能量到达j米所需要的最小时间。
状态转移方程 dp[i][j + l][l*l + k] = min(dp[i][j + l][l*l + k],dp[i][j][k] + 1)
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<stdio.h>
#include<string>
#include<cstring>
#include<map>
#include<vector>
#include<set>
using namespace std;
#define LL long long
#define inf 0x7ffffff
#define N 105
int n,d,e;
int dp[25][N][N];
void deal()
{
for(int i = 0;i <= n;i++)
{
for(int j = 0;j <= d;j++)
{
for(int k = 0;k <= e;k++)
{
dp[i][j][k] = inf;
}
}
}
for(int i = 0;i <= d;i++)
{
dp[1][i][i] = i;
}
}
void show(int x)
{
for(int i =0;i <= d;i++)
{
for(int j = 0;j <= e;j++)
{
cout<<dp[x][i][j]<<' ';
}
cout<<endl;
}
}
int main()
{
int i,j,k,l;
while( cin>>n>>e>>d )
{
deal();
for(i = 0;i <= d;i++)
{
for(j = 0;j <= e;j++)
{
for(k = 0;k*k + j <= e;k++)
{
dp[1][i + k][j + k*k] = min(dp[1][i + k][j + k*k],dp[1][i][j] + 1);
}
}
}
// show(1);
for(i = 2;i <= n;i++)
{
for(j = 0;j <= d;j++)
{
for(k = 0;k <= e;k++)
{
dp[i][j][j] = min(dp[i][j][j],dp[i - 1][j][k]);
}
}
for(j = 0;j <= d;j++)
{
for(k = 0;k <= e;k++)
{
for(l = 0;l*l + k <= e;l++)
{
dp[i][j + l][l*l + k] = min(dp[i][j + l][l*l + k],dp[i][j][k] + 1);
}
}
}
}
int ans = inf;
for(i = 1;i <= n;i++)
{
for(k = 1;k <= e;k++)
{
ans = min(ans,dp[i][d][k]);
}
}
if(ans == inf)
cout<<0<<endl;
else
cout<<ans<<endl;
}
return 0;
}