Codeforces 448D(动态规划、类H数)

这道题可以用类似H数(Humble Number)的方法做。

用一个结构体数组f[1..n]记录1的倍数、2的倍数、3的倍数、……n的倍数。

初始时,全部都是1倍。如,N=5,M=5时,

i12345
f[i].num12345
f[i].cnt11111
f[i].multi12345
其中,f[i].num表示基数,f[i].cnt表示基数的几倍,f[i].multi表示倍数。

再将它们按multi从小到大排序,取出最小的一个或几个,计数。

之后,被取出的结构体cnt加一,变成:

i

1

2

3

4

5

F[i].num

1

2

3

4

5

F[i].cnt

2

1

1

1

1

F[i].multi

2

2

3

4

5

第一小的数是1.

再取出两个2:

i

1

2

3

4

5

F[i].num

1

2

3

4

5

F[i].cnt

3

2

1

1

1

F[i].multi

3

4

3

4

5

第二、第三小的数均是2.

排序:

i

1

2

3

4

5

F[i].num

1

3

2

4

5

F[i].cnt

3

1

2

1

1

F[i].multi

3

3

3

4

5

再取……

以此类推。

运用QSORT可以大大加快排序速度。

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
struct p{
	long long cnt,num,multi;
}f[500002];
int cmp(const void *a,const void *b){
	long long k;
	k=(*(p *)a).multi-(*(p *)b).multi;
	if(k>0)return 1;
	if(k==0)return 0;
	if(k<0)return -1;
}
int main(){
	long long i,temp,j,I;
	long long k;
	long long n,m;
	scanf("%I64d %I64d %I64d",&n,&m,&k);
	if(n>m){
		temp=n;n=m;m=temp;
	}
	memset(f,0,sizeof(f));
	for(i=0;i<n;i++){
		f[i].cnt=1;
		f[i].num=i+1;
		f[i].multi=(i+1);
	}
	i=j=0;
	while(j<k){
	printf("I=%d, J=%d\n",i,j);
	qsort(f,n,sizeof(f[0]),cmp);
	temp=f[0].multi;
	f[0].cnt++;
	f[0].multi=f[0].cnt*f[0].num;
	j++;
	i=1;
		while(f[i].multi==temp){
			f[i].cnt++;
			f[i].multi=f[i].cnt*f[i].num;
			i++;j++;
		}
	}
	printf("%I64d",f[i-1].multi-f[i-1].num);
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值