poj 1946
题目大意:有n只奶牛进行骑自行车环跑,一分钟跑x圈,领跑的消耗x * x体力,而后面跟跑的消耗x体力。
现在输入N, E, D表示有N头奶牛,每头奶牛原先所具有的能量为E,D表示需要环跑的圈数。注意:只要有一只奶牛先达到D圈,就算完成环跑,
问奶牛能否完成环跑,如果不能,输出0,否则,输出环跑的最短时间。
思路: 最优解必为奶牛1..n-1轮流领跑,奶牛n撞线。且跑了x圈后,未领跑过的奶牛都耗费了x的体力。
设dp[i][j][k]表示前i-1头奶牛已领跑,现在由第i头奶牛领跑,一共跑了j圈,奶牛i耗费了k的体力。
则dp[i][j][k]可以转移到dp[i][j + p][k + p2](耗费1分钟,奶牛i以p圈/分钟的速度继续领跑),也可转移到dp[i + 1][j][j](换成奶牛i + 1领跑,不耗费时间)。
好题。
#include<iostream>
#include<fstream>
using namespace std;
int n,e,d;
int dp[21][101][101];
void read(){
int i,j,k,s,t;
// ifstream cin("in.txt");
cin>>n>>e>>d;
for(i=0;i<=n;i++)
for(j=0;j<=d;j++)
for(k=0;k<=e;k++)
dp[i][j][k]=100000000;
dp[1][0][0]=0;
for(i=1;i<=n;i++)
for(j=0;j<d;j++)
for(k=0;k<=e;k++)
if(dp[i][j][k]!=100000000)
{
for(s=0;s+j<=d&&s*s+k<=e;s++)
dp[i][j+s][k+s*s]=min(dp[i][j+s][k+s*s],dp[i][j][k]+1);
if(i<n) dp[i+1][j][j]=min(dp[i+1][j][j],dp[i][j][k]);
}
j=100000000;
for(i=0;i<=e;i++)
j=min(j,dp[n][d][i]);
cout<<j<<endl;
}
int main(){
read();
return 0;
}
浙公网安备 33010602011771号