这DP虽然简单

但是思考一下还是挺好的

题意是

1,2,3,4....k 用加法凑成N

每个数可取不限个数

令dp[i][j] 表示前i种数凑成j的方案数

然后dp[i][j] = dp[i - 1][j] + dp[i - 1][j - i] + dp[i - 1][j - 2 * i]........dp[i - 1][j - k * i]

这样子

然后代码如下,由于结果要爆long long ,所以用两个long long 数存高位和低位

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#define MAXN 111111
#define INF 1000000007
using namespace std;
pair<long long, long long> dp[111][1111];
long long mod = 10000000000000000LL;
int n, m;
int main()
{
scanf("%d%d", &n, &m);
dp[0][0].second = 1;
dp[0][0].first = 0;
for(int i = 1; i <= m; i++)
{
for(int j = 0; j <= n; j++)
for(int k = j; k >= 0; k -= i)
{
dp[i][j].first += dp[i - 1][k].first;
dp[i][j].second += dp[i - 1][k].second;
if(dp[i][j].second >= mod)
{
dp[i][j].first += dp[i][j].second / mod;
dp[i][j].second %= mod;
}
}
}
if(dp[m][n].first > 0)
printf("%I64d%I64d\n", dp[m][n].first, dp[m][n].second);
else printf("%I64d\n", dp[m][n].second);
return 0;
}

然后就是优化一下

dp[i][j] = dp[i - 1][j] + dp[i - 1][j - i] + dp[i - 1][j - 2 * i]........dp[i - 1][j - k * i]

其实可以发现

dp[i][j - k * i] 与dp[i][j - (k - 1)i] 之间是可以转移的

无非是多用了一个i而已

那么优化成了dp[i][j] = dp[i - 1][j] + dp[i][j - i]

dp[i - 1][j] 代表的是前i-1种数凑成j的方案数

dp[i][j - i]代表的是是用了前i种数凑成j - i的方案数

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#define MAXN 111111
#define INF 1000000007
using namespace std;
pair<long long, long long> dp[111][1111];
long long mod = 10000000000000000LL;
int n, m;
int main()
{
scanf("%d%d", &n, &m);
dp[0][0].second = 1;
dp[0][0].first = 0;
for(int i = 1; i <= m; i++)
{
for(int j = 0; j <= n; j++)
{
dp[i][j] = dp[i - 1][j];
if(j - i < 0) continue;
dp[i][j].first += dp[i][j - i].first ;
dp[i][j].second += dp[i][j - i].second;
if(dp[i][j].second >= mod)
{
dp[i][j].first += dp[i][j].second / mod;
dp[i][j].second %= mod;
}
}
}
if(dp[m][n].first > 0)
printf("%I64d%I64d\n", dp[m][n].first, dp[m][n].second);
else printf("%I64d\n", dp[m][n].second);
return 0;
}

然后还能优化的就是空间了

观察转移方程

dp[i][j] = dp[i - 1][j] + dp[i][j - i]

发现只跟i和i-1有关系

并且和i - 1有关系得时候跟j没关系

也就是可以用一个一维的状态转移方程就行了

dp[j] = dp[j] + dp[j - i]

其中dp[i - 1][j]实际上在i - 1 循环后已经隐含的转移到了dp[i][j]中了

也就是dp[j]

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#define MAXN 111111
#define INF 1000000007
using namespace std;
pair<long long, long long> dp[1111];
long long mod = 10000000000000000LL;
int n, m;
int main()
{
scanf("%d%d", &n, &m);
dp[0].second = 1;
dp[0].first = 0;
for(int i = 1; i <= m; i++)
{
for(int j = 1; j <= n; j++)
{
if(j - i < 0) continue;
dp[j].first += dp[j - i].first ;
dp[j].second += dp[j - i].second;
if(dp[j].second >= mod)
{
dp[j].first += dp[j].second / mod;
dp[j].second %= mod;
}
}
}
if(dp[n].first > 0)
printf("%I64d%I64d\n", dp[n].first, dp[n].second);
else printf("%I64d\n", dp[n].second);
return 0;
}

POJ 3181 Dollar Dayz 简单DP的更多相关文章

  1. POJ 3181 Dollar Dayz(全然背包+简单高精度加法)

    POJ 3181 Dollar Dayz(全然背包+简单高精度加法) id=3181">http://poj.org/problem?id=3181 题意: 给你K种硬币,每种硬币各自 ...

  2. POJ 3181 Dollar Dayz && Uva 147 Dollars(完全背包)

    首先是 Uva 147:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_p ...

  3. poj 3181 Dollar Dayz(完全背包)

    Dollar Dayz Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5419   Accepted: 2054 Descr ...

  4. POJ 3181 Dollar Dayz DP

    f[i][j]=f[i-j][j]+f[i][j-1],结果很大需要高精度. //#pragma comment(linker, "/STACK:1024000000,1024000000& ...

  5. poj 3181 Dollar Dayz (整数划分问题---递归+DP)

    题目:http://poj.org/problem?id=3181 思路:将整数N划分为一系列正整数之和,最大不超过K.称为整数N的K划分. 递归:直接看代码: 动态规划:dp[i][j]:=将整数i ...

  6. POJ 3181 Dollar Dayz(高精度 动态规划)

    题目链接:http://poj.org/problem?id=3181 题目大意:用1,2...K元的硬币,凑成N元的方案数. Sample Input 5 3 Sample Output 5 分析: ...

  7. POJ 3181 Dollar Dayz ( 完全背包 && 大数高精度 )

    题意 : 给出目标金额 N ,问你用面额 1~K 拼成 N 的方案有多少种 分析 : 完全背包的裸题,完全背包在 DP 的过程中实际就是列举不同的装填方案数来获取最值的 故状态转移方程为 dp[i] ...

  8. POJ 3181 Dollar Dayz (完全背包,大数据运算)

    题意:给出两个数,n,m,问1~m中的数组成n,有多少种方法? 这题其实就相当于 UVA 674 Coin Change,求解一样 只不过数据很大,需要用到高精度运算... 后来还看了网上别人的解法, ...

  9. poj 3181 Dollar Dayz

    题意:给定一个数p,要求用K种币值分别为1,2,3...K的硬币组成p,问方案数,1,2,2和2,2,1算一种方案即与顺序无关,n <= 1000,k <= 100// 用完全背包做了 这 ...

随机推荐

  1. asp.net web api帮助文档的说明

    为asp.net的mvc web api填写自己的帮助文档 1. 加入Help的area(能够通过命令行或其它方式加入) 命令行:Install-Package Microsoft.AspNet.We ...

  2. 与众不同 windows phone (4) - Launcher(启动器)

    原文:与众不同 windows phone (4) - Launcher(启动器) [索引页][源码下载] 与众不同 windows phone (4) - Launcher(启动器) 作者:weba ...

  3. JavaScript(一基本语法)

    本篇博客是对js的一个基本的了解,对于没有js基础的同学来说应该是个入门的基本吧 javascript 是原型化继承来的面向对象的动态类型的区分大小写的客户端的脚本语言.主要目的是为了解决服务器语言, ...

  4. 设计模式 - 装饰者模式(Decorator Pattern) Java的IO类 用法

    装饰者模式(Decorator Pattern) Java的IO类 用法 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26716 ...

  5. Handler和HandlerThread

    1.什么是Handler? SDK中关于Handler的说明例如以下: A Handler allows you to sendand process Messageand Runnable obje ...

  6. [C#基础] 继承

    虚方法和覆写方法 虚方法可以使基类的引用访问"升至"派生类中 可以使用基类引用调用派生类的方法,只需满足下面的条件 派生类的方法和基类的方法有相同的签名和返回类型 基类的方法使用v ...

  7. 转]解析C语言中的sizeof

    解析C语言中的sizeof 一.sizeof的概念 sizeof是C语言的一种单目操作符,如C语言的其他操作符++.--等.它并不是函数.sizeof操作符以字节形式给出 了其操作数的存储大小.操作数 ...

  8. Go成功的项目

    nsq:bitly开源的消息队列系统,性能非常高,目前他们每天处理数十亿条的消息docker:基于lxc的一个虚拟打包工具,能够实现PAAS平台的组建.packer:用来生成不同平台的镜像文件,例如V ...

  9. How to get the source code of the chromium of the specified revision

    I'd like to get the source code of the chromium 34.0.1847.9. gclient config http://src.chromium.org/ ...

  10. flex网上办(苹果)桌面系统仿真

    1.有登录界面 2.能够载入app(每一个app是单独的swf),并可拖动app的图标互相叠加 3.桌面上显示的哪些APP与目录是依据登陆的用户信息.从webservice中读取的(名字.图标信息等) ...