动态规划篇
题意:给一个总钱数 n, 有k件商品,价格分别为为1~k,问将钱花光,有多少种消费方法
思路:这种动态规划题真的没思路,先画了个表来观察一下。
k=3,n=6;
1 2 3 4 5 6
1 1 1 1 1 1 1
2 1 2 2 2 2 2
3 1 2 3 4 5 6
dp[ i ][ j ]=max{dp[ i ][ j -1 ] , dp[ i -1 ][ j] +dp[ i ][ j - 1 ]}
做题的时候怎么推都推不出来
注意:!!!!!!!
这一题数据比较大,有一个很巧妙的方法-------将一个大数分为两块储存
看代码:
//将一个大数分为两块储存
#include<stdio.h>
#include<string.h>
#define MODE 1000000000000000000//对long long 的上限求余 将余数存到另一个数组里面
long long d[110][1010],p[110][1010];
int main()
{
int n,k;
while(~scanf("%d%d",&n,&k))
{
for(int i=0; i<=k; i++)
for(int j=0; j<=n; j++)
{
d[i][j]=0;
p[i][j]=0;
}
for(int i=0; i<=k; i++)
d[i][0]=1;
for(int i=1; i<=k; i++)
{
for(int j=1; j<=n; j++)
{
if(i>j)
{
d[i][j]=d[i-1][j];
p[i][j]=p[i-1][j];
}
else
{
d[i][j]=(d[i-1][j]+d[i][j-i])%MODE;//大数求余
p[i][j]=p[i-1][j]+p[i][j-i]+(d[i-1][j]+d[i][j-i])/MODE;//将另一部分用整除去掉
}
}
}
if(p[k][n])
printf("%lld%lld\n",p[k][n],d[k][n]);
else printf("%lld\n",d[k][n]);
}
return 0;
}