欢迎来到SamXia的博客|

SamXia

园龄:1个月粉丝:1关注:2

数论+dp部分代码

数论

G题 【模板】筛法

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e8+10;
int prime[maxn];
bool vis[maxn];
int main(){
int cnt=0;
int n,q;
cin>>n>>q;
for(int i=2;i<=n;i++)
{
if(vis[i]==0)
prime[++cnt]=i;
for(int j=1;j<=cnt&&prime[j]*i<=n;j++)
{
vis[prime[j]*i]=1;
if(i%prime[j]==0)
break;
}
}
int x;
for(int i=1;i<=q;++i)
cin>>x,cout<<prime[x]<<"\n";
system("pause");
return 0;
}//欧拉筛

L题 【模板】费马小定理

#include<bits/stdc++.h>
#define int long long
using namespace std;
int qpow(int a,int b,int p)
{
int res=1,temp=a;
while(b)
{
if(b&1) res=1ll*res*temp%p;
temp=1ll*temp*temp%p;
b>>=1;
}
return res;
}
signed main()
{
int a,b,p;
cin>>a>>b>>p;
// b%=p-1;
cout<<qpow(a,b,p);
system("pause");
return 0;
}

报数

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int n=1e7+10;
bool tong[n];
int arr[n];
bool cf(int x)
{
while(x)
{
if(x%10==7) return 1;
x/=10;
}
return 0;
}
signed main()
{
// freopen("number.in","r",stdin);
// freopen("number.ans","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
//初始化
for(int i=1;i<=n;++i)
if(cf(i))
for(int j=1;i*j<=n;++j)
tong[j*i]=1;
int cnt=0;
for(int i=1;i<=n;++i)
if(tong[i]==0) arr[++cnt]=i;
int t;
cin>>t;
while(t--)
{
int x;
cin>>x;
int id=lower_bound(arr+1,arr+cnt+1,x)-arr;
if(arr[id]!=x) cout<<-1<<"\n";
else cout<<arr[id+1]<<"\n";
}
}

dp

A题 能量项链

#include<bits/stdc++.h>
using namespace std;
int head[310];//头标记
int tail[310];//尾标记
int f[310][310];//f[i][j]:[i,j]区间中合并的最大价值
int main()
{
int n;
cin>>n;
//根据题意赋值头标记和尾标记(将链n复制拼接为2n长度)
for(int i=1;i<=n;++i)
cin>>head[i];
for(int i=n+1;i<=2*n;++i)
head[i]=head[i-n];
for(int i=1;i<2*n;++i)
tail[i]=head[i+1];
tail[2*n]=head[1];
for(int len=1;len<n;++len)//枚举区间[i,j]的长度
{
for(int i=1,j=i+len;i+len<=2*n;++i,++j)//枚举起始点i和区间结尾j
/*枚举区间[i,j]*/
for(int k=i;k<j;++k)//枚举中转点
f[i][j]=max(f[i][k]+f[k+1][j]+head[i]*tail[k]*tail[j],f[i][j]);//区间dp:能合并就尝试合并
}
int ans=-1;
for(int i=1;i<=n;++i)
ans=max(ans,f[i][i+n-1]);
cout<<ans;
system("pause");
return 0;
}

D题 [SCOI2005] 互不侵犯

#include<bits/stdc++.h>
using namespace std;
long long f[10][100][2010];
bool sta(int s1,int s2)
{
if(((s1<<1)|(s1>>1))&s1)
return 0;
if(((s2<<1)|(s2>>1))&s2)
return 0;
if(((s1<<1)|s1|(s1>>1))&s2)
return 0;
return 1;
}
int get_num(int s)//计算s二进制中有多少个1
{
int ret=0;
while(s)
{
// cout<<(s&1)<<" ";
ret+=(s&1);//取二进制最后一位的1加入ret
s>>=1;//s右移一位
}
return ret;
}
int main()
{
int n,k;
cin>>n>>k;
f[0][0][0]=1;
int maxn=1<<(n);
for(int i=1;i<=n;++i)//枚举当前行i
for(int s1=0;s1<maxn;++s1)//枚举本行状态s1
for(int s2=0;s2<maxn;++s2)//枚举上一行状态s2
{
if(sta(s1,s2)==0)
continue;
for(int num=0;num<=k;++num)//枚举放了的棋子数
{
// cout<<s1<<"\n";
int num_s1=get_num(s1);
// cout<<num_s1<<" ";
if(num-num_s1>=0)//可以进行dp
f[i][num][s1]+=f[i-1][num-num_s1][s2];
}
}
long long ans=0;
for(int i=0;i<maxn;++i)
ans+=f[n][k][i];
cout<<ans;
system("pause");
return 0;
}

本文作者:SamXia

本文链接:https://www.cnblogs.com/SamXia/p/18708807

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   SamXia  阅读(7)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起