题目背景
(poj1664)
题目描述
把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分发(5,1,1和1,1,5是同一种方法)
输入输出格式
输入格式:
第一行是测试数据的数目t(0 <= t <= 20),以下每行均包括二个整数M和N,以空格分开。1<=M,N<=10
输出格式:
对输入的每组数据M和N,用一行输出相应的K。
输入输出样例
输入样例#2: 复制
1
7 3
输出样例#2: 复制
10分暴力代码
8
正解思路:动态规划。
f[i][j]表示放完了前i个苹果后,有j个盘子不为空,有多少种方案。
#include<map> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; map<string,int>vis; int t,n,m,ans; int num[11],bns[11]; void dfs(int x){ if(x==n){ for(int i=1;i<=m;i++) num[i]=bns[i]; sort(num+1,num+1+m);string s; for(int i=1;i<=m;i++) s+=char(num[i]+‘0‘); if(!vis[s]){ ans++,vis[s]=1; } return ; } for(int i=1;i<=m;i++){ bns[i]+=1; dfs(x+1); bns[i]-=1; } } int main(){ scanf("%d",&t); while(t--){ scanf("%d%d",&n,&m); ans=0;dfs(0); cout<<ans<<endl; } }
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int t,n,k,ans; int dp[1000][1000]; int main(){ scanf("%d",&t); while(t--){ scanf("%d%d",&n,&k); dp[0][0]=dp[1][1]=1; for(int i=1;i<=n;i++) for(int j=1;j<=k;j++){ if(i<j){ dp[i][j]=0;continue; } dp[i][j]=max(dp[i-j][j]+dp[i-1][j-1],dp[i][j]); } for(int i=1;i<=k;i++) ans+=dp[n][i]; cout<<ans<<endl;ans=0; memset(dp,0,sizeof(dp)); } }