标签:
Description
Insilput
Output
Sample Input
4 10 20
Sample Output5
42 627
/*/ 思路有点像模拟,先从小的开始排序,用样例1来说 4的位置可以只放1 {1,1,1,1};① 4的位置也可以放一个2 {2,1,1};这时候剩下2个位置,这状态可以做为一个往2个位置里面再去放东西来看 2的位置可以只放1 {1,1}; 对应的4个位置为 {2,1,1};② 2的位置也可以放一个2 {2}; 对应的4个位置为 {2,2};③ 4的位置可以放一个3 {3,1}; ④ 4的位置可以只放一个4 {4}; ⑤ 这就是整个过程. 对于这个过程,如果一开始就是前面往后面去推的话,很容意发现,前面的插小空的状态是可以保存的,用dp保存每一个从x个填满y长度的方法个数。 如果y==x,那就说明已经填满了,最大的填放方法已经放完了。 又因为如果y>x的话,不可能放下去,就直接复制前面的种类次数就是的了,也就是:dp[x][y]=dp[x][x];//不可能往小位置里塞入大的数 直接结果就是dp[n][n]; AC代码: /*/
#include"map" #include"cmath" #include"string" #include"cstdio" #include"vector" #include"cstring" #include"iostream" #include"algorithm" using namespace std; typedef long long LL; const int MX=202; #define memset(x,y) memset(x,y,sizeof(x)) #define FK(x) cout<<"【"<<x<<"】"<<endl int n,dp[MX][MX]; int main() { memset(dp,0); for(int i=1; i<MX; i++) { //把x,y=1的情况都标出来,为1。 dp[i][1]=dp[1][i]=1; } for(int x=2; x<MX; x++) { for(int y=2; y<MX; y++) { if(x<y) dp[x][y]=dp[x][x];//不可能往小位置里塞入大的数 if(x==y)dp[x][y]=dp[x][y-1]+1; //加上放入最大的数的一次。 if(x>y) dp[x][y]=dp[x][y-1]+dp[x-y][y];/* dp[x-y][y] 往x-y大小里面插入y的可能的次数*/ }/* dp[x][y-1] 前面的次数*/ } while(~scanf("%d",&n)) printf("%d\n",dp[n][n]); return 0; }
ACM: HDU 1028 Ignatius and the Princess III-DP
标签:
原文地址:http://www.cnblogs.com/HDMaxfun/p/5731519.html