HDU4427Math Magic (dp+滾動陣列)
題目連結:
題意:
求選定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; }
相關推薦
HDU4427Math Magic (dp+滾動陣列)
題目連結: 題意: 求選定k個數,k個數的和為n,最小公倍數是m的方案數,最後的結果mod 1000000007; 分析: 狀態轉移很好找,難的是自己去實現優化。 狀態轉移方程為 : dp[i+
POJ-3666 Making the Grade 【動態規劃DP+滾動陣列】
題目傳送門 題目:輸入n個數,第i個數字的值為a[i],把第i個數變為j的代價為a[i]-j的絕對值,求把這n個數組成的數列變成單調數列的最小代價。 題解:dp[i][j]表示前i個數最大值為b[j]時的最小代價,即第i個數在總數列中的值為第j小的時候的最小代價。 動態轉移方程:dp
【Codeforces Round #517 (Div. 2, based on Technocup 2019 Elimination Round 2) D. Minimum path】dp+滾動陣列
D. Minimum path 題意 給你一個字元矩陣,起點在左上角,每次可以向右或者向下走,可以改變這個字元矩陣中的k個字元,是這個路徑構成的字串字典序最小。 做法 由於可以改變k個字元,那麼肯定是找到一條路徑,前面至少有k項為a, 後面按照字典序選擇路徑就可以。 所
HDU 1024 簡單dp 滾動陣列
要求:n個正陣列成的序列,整數範圍-32768 ≤ S ≤ 32767,1 ≤ n ≤ 1,000,000,挑出m個無交集的連續子序列使這些序列和最大,並輸出最大值。 方法:二維dp、滾動陣列降維。 1.dp[i][j]表示第一個數到下標為j的數挑出i個連續子序列組成的最大
poj1159 Palindrome (簡單dp&&滾動陣列)
連結: 題意: 至少增添多少個字元可以使原字串變成迴文串 思路: 原字串反轉,求最長公共子序列長度,剩餘的長度就是需要加的字元數 這裡用到了滾動陣列,因為該次的dp其實只取決去前一次的dp
牛客訓練賽36 B題(dp滾動陣列)
2019年第一次比賽,遭逢大敗。。。都不忍心看自己的排名,第一題一直在想該怎麼去優化。發現並不用,直接暴力過。。。心態炸了,第二題是dp題,一開始想到了增加維度以獲得更多資訊,還好死不死的用疲勞度作為第二維。。。結果陣列變成400*81000那麼大。。。一直在推狀態轉移方程還推不出來。。。看了題
POJ 1159 DP+滾動陣列
Palindrome Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 57568 Accepted: 19962 Description A palindrom
hihocoder#1044狀態壓縮dp+滾動陣列
//20ms 0#include<iostream> #include <string.h> #include <stdio.h> using namespace std; #define MAXN 1500 int N,M,Q; i
LeetCode--Best Time to Buy and Sell Stock IV(DP + 滾動陣列)
題意:已知第1天、第2天......第N天的股票價格,每天只能進行一次買或者賣,且規定手裡的股票賣出之前不能買進新的股票,問在最多進行K次交易的情況下,採用最優方案淨利潤能有多少。 分析: 1、設j天完成不超過i次交易能得到的最大收益是f(i,j),顯然f(0,0) =
noip 2015 子串(dp+滾動陣列)
題目大意:給定兩個字串A,B(都是由a,b組成)(長度分別為n,m);你可以在字串A中任擷取k個字串按擷取順序組成字串B,問能擷取的方案數 動態規劃; s[i][j][k]:字串A正要處理第i項了,陣列B匹配正要第j項,已經截取了k個字串,總方案數; f[i][j][
HDU 4576(概率DP+滾動陣列)
Michael has a telecontrol robot. One day he put the robot on a loop with n cells. The cells are numbered from 1 to n clockwise. At first the robot is i
Playing games —— 基本dp+滾動陣列
題目描述 Niuniu likes playing games. He has n piles of stones. The i-th pile has ai stones. He wants to play with his good friend,
POJ1159迴文字串(DP+滾動陣列)
題目的大概意思就是給你一個字串,讓你在任意位置新增任意字元讓它變成一個迴文字串,求最少新增的字元數。 這是一道典型的DP,總體思路就是把逆串搞出來,兩個字串求出一個最大公共子序列的長度,然後拿n減去這
最大子段-n上找m個子段的和為最大-動態規劃-二維dp+滾動陣列dp優化
1.二維dp dp[i][j]代表的是j長度上找到i段,使得i段和最大。(其中最後一段的最後一位一定要是a[j],這句話不理解的可以看看http://blog.csdn.net/qq_36523667/article/details/78598426) 這時最後一段分為兩
1024 Max Sum Plus Plus(DP + 滾動陣列)
題目大意:求m個不相交區間的最大和 解題思路:這題是參考別人的,傳送門 再自己組織一下,用dp[i][j]表示前j個數組組成了i個不相交區間的最大和,其中第j個數字一定在某個區間內 那現在要決策的是,第j個數組是在和別的陣列成了一個區間,還是自己獨立成了一
HDU 4427 Math Magic【dp+優化+滾動陣列】【好題】
Yesterday, my teacher taught us about math: +, -, *, /, GCD, LCM... As you know, LCM (Least common multiple) of two positive numbers can be solved easily
poj 2663 Tri Tiling (狀壓dp+多米諾骨牌問題+滾動陣列反思)
本來直接一波狀壓dpAC的 #include<cstdio> #include<cstring> #include<algorithm> #define REP(i
Happy Matt Friends(利用滾動陣列優化陣列空間的DP)
Happy Matt Friends Time Limit: 6000/6000 MS (Java/Others) Memory Limit: 510000/510000 K (Java/Others) Total Submission(s): 5492 A
【滾動陣列】【狀壓DP】NOI2001炮兵陣地
題目描述 司令部的將軍們打算在N*M的網格地圖上部署他們的炮兵部隊。一個N*M的地圖由N行M列組成,地圖的每一格可能是山地(用“H” 表示),也可能是平原(用“P”表示),如下圖。在每一格平原地形上最多可以佈置一支炮兵部隊(山地上不能夠部署炮兵部隊);一支炮兵部隊在地圖上的攻擊範圍
【poj 1159】 Palindrome DP(類最長公共子序列)+滾動陣列
Palindrome Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 58492 Accepted: 20318 Description A palindrom