hdu2069 :
给出五种硬币,要求用这些面值的硬币构成S,问方案数是多少。经典dp问题。本题如果不限制金币的使用数量的话可以用dp[i]来记录总数为i的方案数,转移方程是dp[i]=dp[i]+dp[i-type[i]],也就是用type[i]硬币算在i中,方案数就是钱总数为i-type[i]的钱数的总方案数加上i钱数本来的方案数。
现在限制了用的硬币的数量最多是100,上一种方案中的dp方法遗漏了很多细节,所以在此需要同时记录使用的金币数量和泾河的数量。可用dp[i][j]表示金额为i用了j没硬币时候的方案数,次数的转移方案就是dp[i][j]=dp[i-type[i]][j-1]+dp[i][j],就是与上一个相比设置了另一个维度来存储所用的金币数。
代码如下:
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef unsigned int ui; 4 typedef long long ll; 5 typedef unsigned long long ull; 6 #define pf printf 7 #define mem(a,b) memset(a,b,sizeof(a)) 8 #define prime1 1e9+7 9 #define prime2 1e9+9 10 #define pi 3.14159265 11 #define lson l,mid,rt<<1 12 #define rson mid+1,r,rt<<1|1 13 #define scand(x) scanf("%llf",&x) 14 #define f(i,a,b) for(int i=a;i<=b;i++) 15 #define scan(a) scanf("%d",&a) 16 #define mp(a,b) make_pair((a),(b)) 17 #define P pair<int,int> 18 #define dbg(args) cout<<#args<<":"<<args<<endl; 19 #define inf 0x7ffffff 20 inline int read(){ 21 int ans=0,w=1; 22 char ch=getchar(); 23 while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();} 24 while(isdigit(ch))ans=(ans<<3)+(ans<<1)+ch-'0',ch=getchar(); 25 return ans*w; 26 } 27 int n,m,t; 28 const int maxn=300; 29 int type[5]={1,5,10,25,50}; 30 int ans[maxn],dp[maxn][105]; 31 void solve() 32 { 33 dp[0][0]=1; 34 f(i,0,4) 35 { 36 f(j,type[i],251) 37 { 38 f(k,1,100) 39 { 40 dp[j][k]=dp[j][k]+dp[j-type[i]][k-1]; 41 } 42 } 43 } 44 f(i,0,251) 45 f(j,0,100) 46 ans[i]+=dp[i][j]; 47 } 48 int main() 49 { 50 //freopen("input.txt","r",stdin); 51 //freopen("output.txt","w",stdout); 52 std::ios::sync_with_stdio(false); 53 solve(); 54 while (~scanf("%d",&n)) 55 { 56 pf("%d ",ans[n]); 57 } 58 }