将N$的支票换为1$,2$,3$三种硬币

Problem Description:
There are three kinds of coins:1$,2$,3$.Given a chique of N$(0<n<=10^9),calculate the number of different ways to exchange the cheque.
Sample Input:1 2 3
Sample Outpt:1 2 3

也就是说,将N$的支票换为1$,2$,3$三种硬币,问有多少种换法?题目看似简单,问题是,ACM-ICPC对于程序的运行时间是有严格限制的,对于输入为10^9这么大的数要计算出其换法有没有很好的算法,我当时写的花了5秒运行出来,结果还是超时。我不是计算机专业的学生,也没有学过程序设计与算法,抱着学习的心态参加此次比赛,请高手帮解,感激不尽,分数大大的有。

简单:
long Partition(int M){
int V=M/6,i,m=M%6;
long c=3*V*V+3*V+1;
if(m==0)return c;
else return c+m*V+m-1;
}

很简单.首先考虑M是6的倍数的情况,
那么对于任意的y,z
2y+3z<=M我们都有一个解 x=M-2y-3z
所以我们只要数
2y+3z<=M,y>=0,z>=0的数目
而在M是6的倍数时,这个图像在平面上是一个三角形,而且三角形三个顶点都是格点
我们可以直接用格点三角形的面积来计算点的数目:
S=E/2+I-1,其中E表示边界上格点数目,I表示内部的格点数目.(其实直接数格点数目也好数)
而E很容易数出来,这样就可以算出I+E=3*V*V+3*V+1,(V=M/6)
然后,对于M关于6的余数不是0,我们只要计算
2y+3z=6V+1,6V+2,6V+3,...的数目就可以了.
分别对应
2y+3z==6V+t的数目
这个在t=1时,是V个,对于t>1,是V+1个
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值