hdu 5230(整数划分,dp)
生活随笔
收集整理的這篇文章主要介紹了
hdu 5230(整数划分,dp)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=5230
解題思路:
這是一個整數劃分的模型:
將n劃分為k個整數的劃分數
設dp[i][j]為將i劃分為j個整數的劃分數。
(1)?i<j為不可能出現的情況,dp[i][j]=0;
(2) 若i=j,有一種情況:i可以劃分為i個1之和,dp[i][j]=1;
(3) 若i>j,可以根據劃分數中是否含有1分為兩類:若劃分數中含有1,可以使用“截邊法”將j個劃分分別截去一個1,把問題轉化為i-j的j-1個劃分數,為dp[i-j][j-1];?若劃分中不包含1,使用“截邊法”將j個劃分數的最下面一個數截去,將為題轉化為求i-j的j個劃分數,為dp[i-j][j]。所以i>j時dp[i][j]=dp[i-j][j-1]+dp[i-j][j]。
這道題是一樣的,dp[i][j]表示將i劃分成j個不同的數,與上面不同的是,這里當i=j時我們是不處理的,即我們不能出現i=j的情況。
#include<iostream> #include<cstdio> #include<cstring> using namespace std;const int maxn = 100005; const int mod = 998244353; int n,L,R,C,dp[2][maxn];int main() {int t;scanf("%d",&t);while(t--){scanf("%d%d%d%d",&n,&C,&L,&R);L -= C,R = min(R-C,n-1);memset(dp,0,sizeof(dp));dp[0][0] = 1;int ans = L <= 0 ? 1 : 0;for(int i = 1; (1 + i) * i / 2 <= R; i++) //枚舉人數{for(int j = (1 + i) * i / 2; j <= R; j++) //枚舉分數{dp[i & 1][j] = (dp[i & 1][j - i] + dp[(i - 1) & 1][j - i]) % mod; if(L <= j && j <= R)ans = (ans + dp[i & 1][j]) % mod;}memset(dp[(i - 1) & 1],0,sizeof(dp[(i - 1) & 1])); }printf("%d\n",ans);}return 0; }
總結
以上是生活随笔為你收集整理的hdu 5230(整数划分,dp)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hdu 5203(枚举)
- 下一篇: hdu 5265(二分+枚举)