HDU4427Math Magic (dp+滾動陣列)
題目連結:
http://acm.hdu.edu.cn/showproblem.php?pid=4427
題意:
求選定k個數,k個數的和為n,最小公倍數是m的方案數,最後的結果mod 1000000007;
分析:
狀態轉移很好找,難的是自己去實現優化。
狀態轉移方程為 : dp[i+1][s+k][lcm(l,k)]+=dp[i][s][l];
第一維代表的是有多少個數,第二維代表的是這些數的和,第三維代表的是這些數的最小公倍數
因為開不了那麼大的陣列,因此我們要用滾動陣列,詳細請見註釋。
程式碼如下:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int mod = 1000000007;
const int maxn = 1005;
inline int gcd(int a,int b)
{
if(b) return gcd(b,a%b);
return a;
}
int dp[2][maxn][maxn];
int fac[1000];
int lcm[maxn][maxn];
void init()//預處理1~1000內的任意兩個數的最小公倍數
{
for(int i=1;i<maxn;i++)
for(int j=i;j<maxn;j++)
lcm[i][j]=lcm[j][i]=i*j/gcd(i,j);
}
int main()
{
init();
int n,m,k;
while(~scanf("%d%d%d",&n,&m,&k)){
memset(dp,0,sizeof(dp));
int tmp = m, cnt=0,v=0;
memset(dp,0,sizeof dp);
for(int i = 1; i<=m; i++)//預處理出m的所有約數,這k個數一定是在m的約數裡面選的
if(m%i==0) fac[cnt++]=i;
for(int i=0; i<cnt; i++)//初始化
dp[v][fac[i]][fac[i]]=1;
for(int i=1; i<k; i++) //列舉長度
{
memset(dp[v^1],0,sizeof(dp[v^1]));
for(int j=i; j<n; j++) //列舉sum
{
for(int p=0; p<cnt; p++) //列舉上一個狀態的公倍數
{
int mul=fac[p];
if(!dp[v][j][mul])
continue;
for(int q=0; q<cnt; q++) //列舉因子
{
int tt=j+fac[q];//計算當前狀態的和
if(tt>n)
break;
int t = lcm[mul][fac[q]];//當前狀態的最小公倍數
dp[v^1][tt][t]+=dp[v][j][mul];//當前狀態等於之前所有可以達到這個狀態的狀態的和
dp[v^1][tt][t]%=mod;
}
}
}
v^=1;
}
printf("%d\n",dp[v][n][m]);
}
return 0;
}
相關文章
- HDU 4427 Math Magic【dp+優化+滾動陣列】【好題】優化陣列
- 演算法基礎:動態規劃陣列中滾動陣列的使用演算法動態規劃陣列
- 序列(dp+矩陣加速)矩陣
- HDU4991 Ordered Subsequence (dp+樹狀陣列+離散化)陣列
- POJ 3744 概率dp+矩陣矩陣
- 巨大的數(dp+矩陣加速)矩陣
- 幸運數(dp+矩陣加速)矩陣
- 2-7 陣列:動態陣列陣列
- 動態陣列陣列
- 陣列004 動態建立一維陣列陣列
- 建立動態陣列陣列
- List介面(動態陣列)陣列
- HDU 3530 Subsequence (dp+單調佇列)佇列
- poj3017 dp+單調佇列佇列
- 分組(狀壓dp+技巧:快速列舉子集)
- C++動態建立二維陣列,二維陣列指標,以及動態二維陣列函式傳遞C++陣列指標函式
- 手動實現ArrayList動態陣列陣列
- TPU &“脈動陣列”(systolic array)陣列
- JavaSE 陣列:一維陣列&二維陣列Java陣列
- [JAVA] Java 陣列、多維陣列,動態、靜態初始化,陣列JVM記憶體模型分析Java陣列JVM記憶體模型
- EasyUI - DataGrid 去右邊空白滾動條列UI
- 陣列,陣列類,SyStem類陣列
- 陣列結構之陣列陣列
- Java陣列03:陣列使用Java陣列
- 動態陣列介紹----Delphi (轉)陣列
- 動態record陣列的應用陣列
- 陣列1——求一個陣列的最大子陣列陣列
- HDU3519Lucky Coins Sequence(DP+矩陣加速)矩陣
- EasyUI-DataGrid去右邊空白滾動條列UI
- 陣列--移除陣列中指定的元素,不改變原陣列和改變原陣列陣列
- 陣列二:使用陣列可變函式為陣列排序陣列函式排序
- 指標陣列和陣列指標與二維陣列指標陣列
- 動手編寫—動態陣列(Java實現)陣列Java
- Javascript - 陣列和陣列的方法JavaScript陣列
- 陣列指標,指標陣列陣列指標
- 陣列指標 指標陣列陣列指標
- div滾動條樣式,水平滾動
- 隱藏滾動條保留滾動效果