UVA - 10313 Pay the Price
2013-09-22 16:45
281 查看
题意:在1-300之间,给你n,如果后面没跟着数字,代表用1-n的的种数凑成n,如果有一个数的话代表用1-l1种数凑成n,如果还有l2,代表用种数大于l1,小于l2的数凑成n,这貌似没思路啊,枚举的话好像不是太可能啊,后来看到这题涉及到一个结论ferrers图的性质:数n拆分成k个数的和的拆分数,和数n拆分成最大数为k的拆分数相等,然后就用
dp[i][j]代表用大小不超过j的数凑成i的方法个数,还是选与不选的考虑,如果选j的话,dp[i][j] = dp[i-j][j],不选的话
dp[i][j] = dp[i][j-1],所以dp[i][j] = dp[i][j-1] + dp[i-j][j],当然如果i < j的话,那么就只能用j-1去凑,至于能不能凑又是之前的事啦
dp[i][j]代表用大小不超过j的数凑成i的方法个数,还是选与不选的考虑,如果选j的话,dp[i][j] = dp[i-j][j],不选的话
dp[i][j] = dp[i][j-1],所以dp[i][j] = dp[i][j-1] + dp[i-j][j],当然如果i < j的话,那么就只能用j-1去凑,至于能不能凑又是之前的事啦
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int MAXN = 305; long long dp[MAXN][MAXN]; char str[1000]; int main(){ for (int i = 0; i <= 300; i++){ dp[i][0] = i?0:1; //初始化 for (int j = 1; j <= 300; j++) if (i >= j) dp[i][j] = dp[i-j][j] + dp[i][j-1]; else dp[i][j] = dp[i][j-1]; } while (gets(str)){ int n,l1=-1,l2=-1; sscanf(str,"%d %d %d",&n,&l1,&l2); l1 = min(l1,300); l2 = min(l2,300); if (l1 == -1) printf("%lld\n",dp ); else if (l2 == -1) printf("%lld\n",dp [l1]); else { if (l1 == 0) printf("%lld\n",dp [l2]); else printf("%lld\n",dp [l2]-dp [l1-1]); } } return 0; }
相关文章推荐
- UVa 10313 Pay the Price(类似数字分解DP)
- UVA10313- Pay the Price
- UVA - 10313 Pay the Price 整数的划分问题 01背包
- UVA 10313 Pay the Price
- UVA - 10313 Pay the Price
- uva 10313 - Pay the Price
- UVA - 10313 Pay the Price
- UVA - 10313Pay the Price(完全背包)
- uva 10313 Pay the Price(完全背包)
- UVA 10313 Pay the Price
- uva 10313 - Pay the Price
- UVA 10313-Pay the Price(DP)
- uva 10313 Pay the Price(完全背包)
- UVa 10313 Pay the Price (DP&整数拆分)
- UVA 10313 Pay the Price
- 解题报告(一):uva 10313 - Pay the Price (dp)
- UVa 10313 - Pay the Price
- uva 10313 Pay the Price
- dp(整数拆分 uva10313 - Pay the Price)
- UVA 10313 Pay the Price