看到數據量大到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;
}