Poj1958
概述:四柱汉诺塔
知识点:递推
思路:将四柱转化为三柱,假如有N个,那么先把i个放到2号柱上,剩下n-i个放3号柱上,再分别放到4柱上,由此可推递推式
#include<iostream>
#include<cstdio>
#include<cmath>
#include<vector>
#include<algorithm>
#include<string>
#include<cstring>
using namespace std;
int main() {
int a[20],b[20];
memset(b,0x3f,sizeof(b));
for(int i=1;i<12;i++){
a[i]=(1<<i)-1;
}
b[1]=1;
for(int i=2;i<=12;i++){
for(int j=1;j<i;j++) {
b[i]=min(b[i],(b[j]<<1)+a[i-j]);
}
}
for(int i=1;i<=12;i++){
cout<<b[i]<<" ";
}
return 0;
}
POJ1845 Sumdiv
知识点:二分,快幂,等比数列
思路:分解质因数,重的因数可以看成幂的形式,求这个幂的底数的0到n次幂的和,就可以转化为一个等比数列求和,但那样会超时,因此加上一点二分来求和,注意开longlong
#include<iostream>
#include<cstdio>
#include<cmath>
#include<vector>
#include<algorithm>
#include<string>
#include<cstring>
using namespace std;
long long m;
long long y[1000];//存约数
long long c[1000];//存约数个数
long long quickmi(long long a,long long b){
long long ans=1;
while(b>0){
if(b&1){
ans=ans*a%9901;
}
a=a*a%9901;
b>>=1;
}
return ans;
}
void fen(long long n){
m=0;
for(int i=2;i<=sqrt(n);i++){
if(n%i==0){
y[++m]=i;
c[m]=0;
}
while(n%i==0){//处理约数的次方的情况
n/=i;
c[m]++;
}
}
if(n>1){//存储剩下的无法除尽的部分 如自己
y[++m]=n;
c[m]=1;
}
}
long long sum(long long p,long long num){
if(num==0){
return 1;
}
if(num==1){
return p%9901+1;
}
if(num&1){
return ((1+quickmi(p,(num+1)/2))*sum(p,(num-1)/2))%9901;
}else{
return ((1+quickmi(p,num/2))*sum(p,num/2-1)+quickmi(p,num))%9901;
}
}
int main(){
long long a,b;
cin>>a>>b;
if(a==1){
cout<<1;
return 0;
}
fen(a);
long long ans=1;
for(int i=1;i<=m;i++){
ans=(ans*(sum(y[i],c[i]*b)%9901))%9901;
}
cout<<ans<<endl;
return 0;
}
bzoj1218(网站打不开了)
思路:维护一个二维前缀和,然后枚举所有边长为r的正方形,更新答案
知识点:二维前缀和:自己加上加左减去左下
#include<iostream>
#include<cstdio>
#include<cmath>
#include<vector>
#include<algorithm>
#include<string>
#include<cstring>
using namespace std;
int a[5050][5050];
int main(){
int n,r,ans=-1;
cin>>n>>r;
for(int i=1;i<=n;i++) {
int x,y,v;
cin>>x>>y>>v;
a[x+1][y+1]=v;
}
for(int i=1; i<5001; i++) {
for(int j=1; j<5001; j++) {
a[i][j]+=a[i][j-1]+a[i-1][j]-a[i-1][j-1];
}
}
for(int i=1; i<5001; i++) {
for(int j=1; j<5001; j++) {
if(i-r>=0&&j-r>=0) {
ans=max(ans,a[i][j]-a[i-r][j]-a[i][j-r]+a[i-r][j-r]);
}
}
}
cout<<ans;
return 0;
}