HDU 3348

下面这个代码超时,也不知道是否完全正确,大家可以自己出一组测试数据,如果有错误,麻烦留言。


#include "stdio.h"
#include "string.h"

int cos[5] = {1, 5, 10, 50, 100};
int money;
int all[5];
int max[5], m[5];
int sum[5];

void reverse(){
	int t;
	int i;
	
	memset(m, 0, sizeof(m));

	t = cos[0]; cos[0] = cos[4]; cos[4] = t;
	t = cos[1]; cos[1] = cos[3]; cos[3] = t;
	t = all[0]; all[0] = all[4]; all[4] = t;
	t = all[1]; all[1] = all[3]; all[3] = t;

	sum[0] = all[0]*cos[0];
	for(i=1; i<5; i++)
		sum[i] = sum[i-1] + all[i]*cos[i];
}

int get(int now, int lev){
	int i = lev;
	int mark;
	if(lev<0 && now) return 0; /*已经到底层,而且钱还没抵消完*/
	while(now>=cos[i] && all[i]>m[i]){
		now -= cos[i];
		m[i]++;
	}
	if(!now) return 1;
	if(lev>=1 && now>sum[lev-1]) return 0;
	while(!(mark=get(now, lev-1))){
		if(!m[i]) break;
		m[i]--;
		now += cos[i];
	}
	return mark;
}

void main(){
	int n;
	int i, j;
	freopen("in.txt", "r", stdin);
	while(scanf("%d", &n)!=EOF){
		for(i=0; i<n; i++){
			scanf("%d %d %d %d %d %d", &money, all, all+1, all+2, all+3, all+4);

			memset(m, 0, sizeof(m));
			sum[0] = all[0]*cos[0];
			for(j=1; j<5; j++)
				sum[j] = sum[j-1] + all[j]*cos[j];
			
			if(money<=sum[4] && get(money, 4)){
				for(j=0; j<5; j++) max[j] = m[j];
				reverse();
				if(get(money, 4)){
					printf("%d ", max[0]+max[1]+max[2]+max[3]+max[4]);
					printf("%d\n", m[0]+m[1]+m[2]+m[3]+m[4]);
					reverse();
				}else
					printf("-1 -1\n");
			}else
				printf("-1 -1\n");

		}
	}
}

网上找的代码,看看两者的不同


#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int minnumber( int a[], int num[], int price, int sum[] )
{
    int ans=0;
    for( int i=5;i>1; i-- )
    {
		if( price>=num[i]*a[i] )// 取币值最大的
		{
			ans+=num[i];
			price-=num[i]*a[i];  
		}    
		else
		{
			ans+=price/a[i];
			price%=a[i];    
		}   
    }
    if( price<=num[1] )
		return ans+price;
    return -1;   
}
int maxnumber( int a[],int num[], int price, int sum[] )
{
    int ans=0;
    for( int i=5; i>1; i-- )
    {
        if( price<=sum[ i -1 ] )//取币值最小的
			continue;
        else
        {
            int t=( price - sum[i-1] )/a[i]+(( ( price - sum[ i-1 ] )%a[i] )? 1 : 0);
            ans+=t;
            price=price-t*a[i];
		}    
    }
	
    if( price> num[1] )
		return -1;
	return ans+price;   
}
void DP( int a[], int num[], int price )
{
	int sum[6]={0};
	sum[1]=num[1];
	for( int i=2; i<=5 ;i++ )
	{
		sum[i]=sum[i-1]+a[i]*num[i];
	}
	int min=minnumber( a, num,price,sum );
	if( min==-1 )
		printf( "-1 -1\n" );
	else
	{
        int max=maxnumber( a, num , price , sum );
        if( max!=-1 )
			printf( "%d %d\n",min, max );
        else printf( "-1 -1\n" );    
	}    
}
int  main()
{
	int num[6],price,n,a[6]={0,1,5,10,50,100};
	freopen("in.txt", "r", stdin);
	scanf( "%d",&n );
	for( int i=1; i<=n; i++ )
	{
        int sum=0;
        scanf( "%d",&price );
        for( int j=1; j<6;j++ )
        {
			scanf( "%d",&num[j] );
			sum+=a[j]*num[j];
        }
        if( sum>=price )
			DP( a,num ,price);
        else printf( "-1 -1\n" );
	}
	return 0;    
}

假如,钱不是1,5,10,50,100,而是7,8,9,怎么办?

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值