題目大意:
選擇不超過k個n以內的正整數相乘,使乘積使乙個無平方因子數,問有多少種取法?(每個數只能取一次)1≤
k,n≤
500 。
解題思路:
首先可以想到把有平方因子數的數刪了。
那問題也就變成了使取得的數的質因數集合無交集。
如果質因數個數足夠少,我們就可以狀壓記錄每個質數取還是沒取,但500的範圍太大。
不過注意到每個數最多只會有乙個比n√
大的質因數,所以我們可以把所有數字按照含有哪乙個比n√
大的質因數分組,若沒有則自己分一組,那麼最後每組最多取乙個數,問題也就變成了多組揹包問題。而n
√ 以內的質因數只有8個,就可以狀壓了。
f[i][j][mask]表示計算完了前i組,共選擇了j個數字,mask表示當前的質因數集合有哪些質數。但第一維就像01揹包一樣可以省去。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ll long long
using
namespace
std;
int getint()
const
int n=505,mod=1e9+7;
const
int p[8]=;
int t,n,k;
int yz[n],g[n][n];
int f[n][1
<<8];
void pre()}}
}void div()
}void add(int &x,int y)
int main()
ll ans=0;
for(int i=1;i<=k;i++)
for(int now=0;now<(1
<<8);now++)
ans=(ans+f[i][now])%mod;
cout
<'\n';
}return
0;}
NOIP模擬 乘積(狀壓DP)
題意 選擇不超過 k 個 n以內的正整數撐起來,使得乘積是乙個無平方因子數 不能夠被任意乙個質數的平方整除 一共有多少種取法?n 500,k 500 題解 首先,很容易想到狀壓,壓縮當前已經選過某質數的狀態。對於質數個數小於 20 可以直接過,但是問題是現在 n 以內的質數個數很多,無法壓縮。考慮狀...
NOI P模擬賽 奶油蛋糕塔(狀壓 DP)
資料範圍1 n 5 1 051 leq n leq5 times10 5 1 n 5 105 n 20 n leq 20 n 20 的狀壓應該都會吧,狀態記錄已經選了的蛋糕集合,以及蛋糕序列的尾部奶油,然後列舉蛋糕轉移。總共有 10 1010 種不同的蛋糕,資料很小。把最後的蛋糕塔等效為乙個序列,如...
校內模擬 記憶(狀壓DP)
考場想到了正解,然後被卡快取記憶體,gg 乙個顯然的轉化就是設e ie i ei 表示朋友選擇第i ii個串的時候的期望操作次數。則答案就是所有e ie i ei 的平均值。首先考慮乙個o n l2l o nl2 l o nl2l 的暴力,對於每個串,列舉所有其他串看有多少個位置相同,則我們能夠知道...