(1)拼凑面额
1)暴力递归:O(aim^N):70%
2)记忆化搜索:O(N*aim^2):80%
3)动态规划:O(N*aim),O(N*aim) dp[i][j] = dp[i-1][j] + dp[i][j-arr[i]]
4)动态规划+空间压缩:O(N*aim),O(aim)
#include<iostream>
#include<vector>
using namespace std;
#define MAX 10001
#define n 6
int arr[n] = {1,5,10,20,50,100};
long coins1(int index,int aim)//暴力递归,case:70%
{
int i;
long res=0;
if(index==n)
res= aim==0?1:0;
else{
for(i=0;arr[index]*i<=aim;i++)
{
res+=coins1(index+1,aim-arr[index]*i);
}
}
return res;
}
long coins2(int index,int aim)//记忆搜索 90ms,776k
{
int i;
long res=0;
long map[n+1][aim+1]={0};
if(index==n)
res= aim==0?1:0;
else
{
for(i=0;arr[index]*i<=aim;i++)
{
int value = map[index+1][aim-arr[index]*i] ;
if(value!=0)
{
res += value==-1?0:value;
}
else
res+=coins2(index+1,aim-arr[index]*i);
map[index][aim] = res==0?-1:res;
}
}
return res;
}
long search1(int aim)//动态规划1 运行时间:4ms 占用内存:896k
{
int i,j;
long dp[n][aim+1];
for(j=0;j<n;j++)
{
dp[j][0]=1;
}
for(i=0;arr[0]*i<=aim;i++)
{
dp[0][arr[0]*i] = 1;
}
for(i=1;i<n;i++)
{
for(j=1;j<=aim;j++)
{
dp[i][j] = dp[i-1][j];
dp[i][j] += j-arr[i]>=0?dp[i][j-arr[i]]:0;
}
}
return dp[n-1][aim];
}
long search2(int aim)//空间压缩 运行时间:3ms 占用内存:616k
{
int i,j;
long dp[aim+1];
for(j=0;arr[0]*j<=aim;j++)
dp[arr[0]*j] = 1;
for(i=1;i<n;i++)
for(j=1;j<=aim;j++)
dp[j]+=j-arr[i]>=0?dp[j-arr[i]]:0;
return dp[aim];
}
int main()
{
int i,N;
long sum;
cin>>N;
if(N<0)
sum = 0;
else
{
//sum = coins1(0,N);
//sum = coins2(0,N);
//sum = search1(N);
sum = search2(N);
}
cout<<sum<<endl;
return 0;
}