Luogu P2386 放苹果

来源:互联网 发布:js如何覆盖css效果 编辑:程序博客网 时间:2024/06/05 22:44

题目传送门:https://www.luogu.org/problem/show?pid=2386


主要思路:要做出这道题首先要理解题目(题目略坑).
就是给你x个苹果,然后要把它们放在y个盘子上,要把苹果全放完,但是可以有盘子没放.
然后呢,就是求有多少种方案,但是盘子没有顺序,也就是1 5,5 1是同一种方案.
我们可以用dp[x][y],来表示将x个苹果放在y个盘子上的方案总数.
如果现在只有一个苹果,y个盘子(假设y为3),那么0 0 1,1 0 0,0 1 0,都是一种方案,所以当苹果数
为1时,dp[1][y]=1.
再如果现在只有一个盘子,y个苹果,前面也说了苹果要全放完,所以dp[y][1]=1.
但是如果现在正好苹果与盘子的个数一样呢,我们来分析一下:可以每个盘子放一个,方案为1,还可以当前这个盘子不放,方案为dp[x][y-1],所以当苹果与盘子一样多时,dp[x][y]=dp[x][y-1]+1.
那再看一下,如果现在苹果比盘子少呢,那只可以放满x个盘子,所以等于dp[x][x].
最后还有一种情况,就是苹果比盘子多的情况下,我们可以当前这个盘子不放,也就是
dp[x][y-1],还可以先把每个盘子都放一个,再回来看,也就是dp[x][y-1]+dp[x-y][y].
由上所述,我们可以得出下面这几条状态转移方程:
dp[x][y]=1                                         x=1 || y=1
dp[x][y]=dp[x][y-1]+1                        x=y
dp[x][y]=dp[x][x]                               x<y
dp[x][y]=dp[x][y-1]+dp[x-y][y]           x>y


附上代码:

#include <iostream>using namespace std;int dp[201][201],n,m,s,i,j;int main(){for(i=1;i<=200;i++){for(j=1;j<=200;j++){if(i==1 || j==1){dp[i][j]=1;}if(i>j){dp[i][j]=dp[i][j-1]+dp[i-j][j];}if(i==j){dp[i][j]=dp[i][j-1]+1;}if(i<j){dp[i][j]=dp[i][i-1]+1;}}}cin>>s;for(i=1;i<=s;i++){cin>>n>>m;cout<<dp[n][m]<<endl;}}