UCF Local Programming Contest 2014(Practice)
Your math teacher Xavier Guha has given your class an extra credit assignment to work on. The problem he gives is as follows: Given a linear equation of the form
c 1 x 1 + c 2 x 2 + c 3 x 3 + c 4 x 4 + c 5 x 5 + c 5 x 5 + c 6 x 6 + c 7 x 7 + c 8 x 8 = N c_1x_1 + c_2x_2 + c_3x_3 + c_4x_4 + c_5x_5 + c_5x_5 + c_6x_6 + c_7x_7 + c_8x_8 = N c1x1+c2x2+c3x3+c4x4+c5x5+c5x5+c6x6+c7x7+c8x8=N
Having taken several programming classes from his brother, you decide to prove your teacher wrong by writing a program to determine how many solutions the equation has.
题意:给出c1……c8 和 N 求有多少种非负整数解。
我们可以考虑记忆化搜索:
Code1:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
int n;
int a[9];
LL dp[10][110];
LL dfs(int x,int sum)
{
if(sum==n) return 1;
if(x>8||sum>n) return 0;
if(dp[x][sum]>=0) return dp[x][sum];
return dp[x][sum] = dfs(x+1,sum)+dfs(x,sum+a[x]); //不选第x个和选第x个
}
int main()
{
int T;
cin>>T;
for(int i=1;i<=T;i++){
for(int j=1;j<=8;j++) cin>>a[j];
cin>>n;
memset(dp,-1,sizeof dp);
dfs(1,0);
cout<<"Equation #"<<i<<": "<<dp[1][0]<<"\n";
}
return 0;
}
完全背包:
Code2:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
LL dp[10][110]; //前i个数,装满大小为j的背包的种类数;
int a[10];
int main()
{
int T,m,K=1;
cin>>T;
while(T--){
for(int i=1;i<=8;i++) cin>>a[i];
memset(dp,0,sizeof dp);
for(int i=0;i<=8;i++) dp[i][0] = 1;
cin>>m;
for(int i=1;i<=8;i++){
for(int j=1;j<=m;j++)
for(int k=0;k*a[i]<=j;k++)
dp[i][j] += dp[i-1][j-k*a[i]];
}
cout<<"Equation #"<<K<<": "<<dp[8][m]<<"\n";K++;
}
return 0;
}
既然是完全背包那我们就可以优化一波
Code3:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
LL dp[110];
int a[10];
int main()
{
int T,m,K=1;
cin>>T;
while(T--){
for(int i=1;i<=8;i++) cin>>a[i];
memset(dp,0,sizeof dp);
dp[0] = 1;
cin>>m;
for(int i=1;i<=8;i++){
for(int j=a[i];j<=m;j++)
dp[j] += dp[j-a[i]];
}
cout<<"Equation #"<<K<<": "<<dp[m]<<"\n";K++;
}
return 0;
}