Dollar Dayz poj3181
http://poj.org/problem?id=3181
這個題目一開始就能看出來是個dp問題,但是我并沒有一開始就看出來是一個完全背包為題,只是想著根據以前的方法,這個問題應該是可以找到規律的,但是,還是被坑了,這還是一個大數問題!
首先我膜拜一下hankcs大神的:
///
hancks的這個做法是用完全背包
dp[i][j] =?dp[i – 1][j] +?dp[i – 1][j – i] +?dp[i?– 1][j – 2 * i] + … +?dp[i?– 1][0]
由這個公式可以再遞推:
將j換成j – i有
dp[i][j – i] =?dp[i – 1][j – i] +?dp[i?– 1][j – 2 * i] +?… +?dp[i?– 1][0]
得出:if j >= i:
dp[i][j] = dp[i-1][j] + dp[i][j-i];
我的做法是一開始就推出了這個公式,因為不小心看出了這個規律
i:1->4 ,j :1->5 dp[i][j]規律是這樣的
1 1 1 1 1
1 2 2 3 3
1 2 3 4 5
1 2 3 4 6? ? ?
得出了j >= i : dp[i][j] = dp[i-1][j] + dp[i][j-i]
然而,這還是個大數問題,即使unsigned long long 都不行,開始一直沒想通!
/*************************************************************************> File Name: DollarDayz_poj3181.cpp> Author: spzhao> Mail: spzhaol@163.com > Created Time: 2015年10月14日 星期三 11時13分22秒************************************************************************/#include<iostream> #include <cstdio> #include <cstring> #include <algorithm>#define mod 10000000000000000 using namespace std;const int N = 1005; const int K = 105; unsigned long long dp[100+16][1000+16][2]; int n,k; void solve() {for (int i = 1;i <= k;i++){for (int j = 1;j <= n;j++){if (j >= i){dp[i][j][0] = dp[i-1][j][0]+dp[i][j-i][0];dp[i][j][1] = dp[i-1][j][1]+dp[i][j-i][1];dp[i][j][0] += dp[i][j][1]/mod;dp[i][j][1] = dp[i][j][1]%mod;}else{dp[i][j][0] = dp[i-1][j][0];dp[i][j][1] = dp[i-1][j][1];}}}if (dp[k][n][0])cout << dp[k][n][0];cout << dp[k][n][1] << endl; } int main () {cin >> n >> k;memset(dp,0,sizeof(dp));dp[1][0][1] = 1;for (int i = 1;i <= k;i++)dp[i][0][1] = 1;solve();return 0; }
?
?
?
?
轉載于:https://www.cnblogs.com/ediszhao/p/4877997.html
總結
以上是生活随笔為你收集整理的Dollar Dayz poj3181的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在Linux下安装aws命令行操作
- 下一篇: SQL Server 个人手册