USACO 2.3.4 Money Systems

这道题是整数拆分的变形。

由于钱币最多只有25种,所以这道题也可以用记忆式搜索、DP来做。

下面贴的是母函数法的代码。

k的初值:如果填l加一个判断条件(t1=k+j*coin[i]<=n),则1.15s超时,

如果在初值上填写n-j*coin[i],则0.319s不超时(第十二个点)。

/*
ID:szwjcch971
LANG:C++
TASK:money
*/
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
/*void swapshuzu(long long a[10035],long long b[10035]){
	long long t;
	b=a;
}*/
int min(int a,int b){
	return a<b?a:b;
}
int main(){
	int coin[26];
	int v,n,temp,i,j,k,l;
	long long t1,t2;
	long long cishu[10035],tem[10035];
	FILE *fin=fopen("money.in","r");
	FILE *fout=fopen("money.out","w");
	fscanf(fin,"%d",&v);
	fscanf(fin,"%d",&n);
	//printf("%d %d\n",v,n);
	for(i=1;i<=v;i++)fscanf(fin,"%d",&coin[i]);
	for(i=1;i<v;i++){
		for(j=i+1;j<=v;j++){
			if(coin[i]>coin[j]){
				temp=coin[i];coin[i]=coin[j];coin[j]=temp;
			}
		}
	}
	memset(cishu,0,sizeof(cishu));
	memset(tem,0,sizeof(tem));
	cishu[0]=1;
	for(i=1;i<=v;i++){
		l=n;
		while(!cishu[l])l--;
		for(j=0;j<=l;j++)tem[j]=cishu[j];
		for(j=1;j<=n/coin[i];j++){
			for(k=min(l,n-j*coin[i]);k>=0;k--){
				//printf("I=%lld,J=%lld,K=%lld,T1=%lld,\n",i,j,k,t1);
				cishu[k+j*coin[i]]+=tem[k];
			}
		}
	}
	fprintf(fout,"%lld\n",cishu[n]);
	return 0;
}

附第12组数据:

Input:

8 10000
1 2 3 4 5 6 20 25

Output:

17166982


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值