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;
}

posted on 2011-02-26 10:18  宇宙吾心  阅读(848)  评论(0)    收藏  举报

导航