第九章例题 9-20 Dropping water balloons UVA - 10934

/*SE:wn------王宁*/
前面是正解,后面的是我自己第一次尝试的代码——仅仅走出了第一步,很有借鉴意义,我也在那里做了一下总结——放在代码中的那一段注释。

/*SE:wn------王宁*/
/*T - Dropping water balloons UVA - 10934 */
#include<bits/stdc++.h>
using namespace std;
const int maxk = 100+5;
const int maxf = 63 +5; 
/*表示用给定气球和给定次数能测最多几层楼*/
unsigned long long d[maxk][maxf];
unsigned long long n;
int k,i,j,ans;

int main()
{
	memset(d,0,sizeof(d));
	for(i=1;i<=100;i++)
		for(j=1;j<=63;j++)
		{
			d[i][j]=1+(d[i-1][j-1])+(d[i][j-1]);
			/*
			这栋高楼呢,其实你并不知道有多少层也不知道一开始应该从哪扔
			如果在某一层破掉了,那么下面的层数必须用 (i-1)个气球配合(j-1)次测试次数给测出来
			所幸的是,我们知道 用 (i-1)个气球配合(j-1)次测试次数 最多能测几层 
			如果没破掉,那么用i个气球配合(j-1)次测试次数还可以再多测几层 
			所幸的是,我们知道 用 (i)个气球配合(j-1)次测试次数 最多能测几层 
			这种建楼方式像不像先造中间再往下往上造? 
			总之,是破和不破的两种可能性决定了最终能测的最高层数
			题外话:long long int的最大值(2^63-1)刚好就是最后的那个9223372036854775807
			这也是我们d的最大值——在i<=100,j<=63的情况下。
			有兴趣自己可以打印出来玩玩…… 
			*/
		}
	while(cin>>k>>n&&k){
		int ans=-1;
		for(i=1;i<=63;i++)
			if(d[k][i]>=n) { ans=i;break;	}
		if(ans==-1) printf("More than 63 trials needed.\n");
		else printf("%d\n",ans);
	}
	return 0;
}

—————我是美貌与智慧并存的分割线————

/*SE:wn------王宁*/
/*T - Dropping water balloons UVA - 10934 */
#include<bits/stdc++.h>
using namespace std;
const int maxn = 100+5;
const int maxb = 7 +5; 
int d[maxb][maxn];
int k,n,i,j,p,sum,ans;
int main()
{
	/*之前在蓝桥杯遇到过扔杯子的题目
	后来看了别人的题解,今天凭着自己理解又写出来了
	但是这个存在的问题就是,楼层数很多,不可能给你开那么大的数组
	想来时间开销也不够
	后来看了刘汝佳大神的原码才知道他把状态给重定义了
	我的状态是给定气球的数量和层数,dp值是最少需要扔几次
	他则是给定气球数量和测试次数,dp值是算出最多能扔几层
	知道了之后,就能利用不等式关系,在气球数目确定的情况下,
	每次多给一次测试次数,找出(第一次能测的最高层数大于等于当前层数)的测试次数
	这就是答案了
	所以以后遇到状态值过大,目标值又很小的题目,应当尝试将状态值重新定义
	*/ 
	d[0][0]=0; //前面是气球的数量,后面是层数
	for(i=1;i<maxn;i++) d[1][i]=i;
	for(i=1;i<maxb;i++) d[i][0]=0;
	for(i=2;i<maxb;i++)
		for(j=1;j<maxn;j++){
			d[i][j]=1000000;
			for(p=1;p<=j;p++){
				ans=-1;
				ans=max(ans,d[i][j-p]+1);
				ans=max(ans,d[i-1][p-1]+1);
				d[i][j]=min(d[i][j],ans);
			}
		}
	printf("%d",d[2][100]); 
	return 0;
}

猜你喜欢

转载自blog.csdn.net/JXUFE_ACMer/article/details/81587399