看到数据量大到1W,我就知道单纯的DFS算法那是肯定会超时的,而且一看也基本上看得出来要用DP来处理。不过今儿有劲儿,看看DP到底能比DFS快多少。
下面是超时代吗。
/*
ID: fairyroad
TASK:money
LANG:C++
*/
#include<fstream>
using namespace std;
ifstream fin("money.in");
ofstream fout("money.out");
int V, N;
long long v[25];
long long dfs(int remainder, int min)
{
if(remainder == 0)
return 1;
else if(remainder < 0) return 0;
long long res = 0;
for(int i = min; i < V; ++i)
{
int times = remainder/v[i];
for(int j = 1; j <= times; ++j)
res+=dfs(remainder-j*v[i], i+1);
}
return res;
}
int main()
{
fin>>V>>N;
for(int i = 0; i < V; ++i) fin>>v[i];
fout<<dfs(N, 0)<<"\n";
return 0;
}
下面是DP的代码,又短又快,够飘逸吧!
设dp[i,j]表示前i种货币构成j的方法数,用cc记录货币的面值,状态转移方程为:
dp[i,j]=dp[i-1,j]+dp[i,j-num[i]]
/*
ID:fairyroad
LANG:C++
TASK:money
*/
#include <fstream>
using namespace std;
ifstream fin("money.in");
ofstream fout("money.out");
int V, N ;
long long dp[10001];
int main()
{
fin>>V>>N;
dp[0]=1;
int num;
for (int i = 1;i <= V; i++)
{
fin>>num;
for (int j = num; j <= N; j++)
dp[j]+=dp[j-num];
}
fout<<dp[N]<<endl;
return 0;
}