hdu4427(dp+数学优化)
2016-10-04 16:27
141 查看
链接:点击打开链接
题意:求k个数和为n,最小公倍数为m的种数
代码:#include <set>
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
const long long MOD=1000000007;
vector<long long> fac;
long long lcm[1005][1005];
long long dp[2][1005][1005];
long long gcd(long long a,long long b){
if(b==0)
return a;
return gcd(b,a%b);
}
int main(){
long long n,m,num,i,j,k,p,q,tmp,len;
for(i=1;i<=1000;i++)
for(j=1;j<=1000;j++)
lcm[i][j]=i/gcd(i,j)*j;
while(scanf("%I64d%I64d%I64d",&n,&m,&num)!=EOF){
fac.clear(); //dp[i][j][k]表示i个数,和为j,最小公倍数是k的种数
for(i=1;i<=m;i++) //直接进行转移一定会超时,因此先处理出j的所欲因子
if(m%i==0)
fac.push_back(i);
len=fac.size();
memset(dp,0,sizeof(dp));
for(i=0;i<len;i++) //因为最小公倍数是m,所以k个数每一个都是m的因子
dp[1][fac[i]][fac[i]]=1; //所以直接在因子中间转移
for(i=1;i<num;i++){
for(p=i;p<=n;p++)
for(q=0;q<len;q++)
dp[(i+1)%2][p][fac[q]]=0; //不能用memset
for(j=i;j<=n;j++){
for(p=0;p<len;p++){
if(dp[i%2][j][fac[p]]==0)
continue;
for(q=0;q<len&&fac[q]+j<=n;q++){
tmp=lcm[fac[p]][fac[q]];
dp[(i+1)%2][j+fac[q]][tmp]=(dp[(i+1)%2][j+fac[q]][tmp]+dp[i%2][j][fac[p]])%MOD;
}
}
}
}
printf("%I64d\n",dp[num%2]
[m]);
}
return 0;
}
题意:求k个数和为n,最小公倍数为m的种数
代码:#include <set>
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
const long long MOD=1000000007;
vector<long long> fac;
long long lcm[1005][1005];
long long dp[2][1005][1005];
long long gcd(long long a,long long b){
if(b==0)
return a;
return gcd(b,a%b);
}
int main(){
long long n,m,num,i,j,k,p,q,tmp,len;
for(i=1;i<=1000;i++)
for(j=1;j<=1000;j++)
lcm[i][j]=i/gcd(i,j)*j;
while(scanf("%I64d%I64d%I64d",&n,&m,&num)!=EOF){
fac.clear(); //dp[i][j][k]表示i个数,和为j,最小公倍数是k的种数
for(i=1;i<=m;i++) //直接进行转移一定会超时,因此先处理出j的所欲因子
if(m%i==0)
fac.push_back(i);
len=fac.size();
memset(dp,0,sizeof(dp));
for(i=0;i<len;i++) //因为最小公倍数是m,所以k个数每一个都是m的因子
dp[1][fac[i]][fac[i]]=1; //所以直接在因子中间转移
for(i=1;i<num;i++){
for(p=i;p<=n;p++)
for(q=0;q<len;q++)
dp[(i+1)%2][p][fac[q]]=0; //不能用memset
for(j=i;j<=n;j++){
for(p=0;p<len;p++){
if(dp[i%2][j][fac[p]]==0)
continue;
for(q=0;q<len&&fac[q]+j<=n;q++){
tmp=lcm[fac[p]][fac[q]];
dp[(i+1)%2][j+fac[q]][tmp]=(dp[(i+1)%2][j+fac[q]][tmp]+dp[i%2][j][fac[p]])%MOD;
}
}
}
}
printf("%I64d\n",dp[num%2]
[m]);
}
return 0;
}
相关文章推荐
- [BZOJ1584][Usaco2009 Mar]Cleaning Up 打扫卫生(dp+数学相关优化)
- CodeForces 833B The Bakery(dp+线段树优化)
- poj 3171 dp+线段树优化
- HDOJ,水题继续,杭电1215,七夕节。关于运算优化的数学题。
- 一道暴力,用数学方法优化
- 数学模型--现代优化算法(启发式算法)
- hdu 5009 Paint Pearls(DP+链表优化)
- JavaScript 高精度数学运算 优化版
- UVA1363 - Joseph's Problem(数学,迷之优化)
- 约瑟夫环问题的数学优化算法-(应用于System Overload zju1088)
- CodeForces - 1017F. The Neutral Zone (数学+Bitset存素数+素数筛优化)
- (转)强大的数学优化建模语言Lingo
- 170525 逆向-数学运算符的优化,CrackMe(2)
- HDU 5009 Paint Pearls(西安网络赛C题) dp+离散化+优化
- 利用数学里的一个漏洞(1=0.9(9循环))来验证JAVA的编译优化
- Codeforces Round #271 (Div. 2)E. Pillars(dp+线段树优化)
- hdu 5009 Paint Pearls(DP+链表优化)
- Noip 2016 组合数问题 - 数学 - 前缀和优化
- Educational Codeforces Round 19 F(dp+队列优化)
- hdu5745 La Vie en rose【dp+bitset优化】