1.数位dp
一般形式:hdu 4722
LL find(int a[],int n)//求0~a的符合条件的数
{
int i,j,k;
memset(c,0,sizeof(c));
int x=0;
for(i=1;i<=n;i++)//从最高位开始,按位dp
{
for(j=0;j<10;j++)
for(k=0;k<10;k++)
c[i][(j+k)%10]+=c[i-1][j];
for(j=0;j<a[i];j++)
c[i][(x+j)%10]++;
x=(x+a[i])%10;
}
if(x==0)c[n][0]++;
return c[n][0];
}
递归形式:hdu 4734
int dfs(int pos,int s,int full)//长度为pos的数,其函数值不大于s的有多少?
{ //full表示是否是边界值,1表示是,0表示不是
if(pos==-1)
{
if(s>=0) return 1;
else return 0;
}
if(s<0) return 0;
if(!full&&dp[pos][s]!=-1) return dp[pos][s];
int en,ans=0,i;
en=(full?b[n-pos-1]-'0':9);
for(i=0;i<=en;i++)
ans+=dfs(pos-1,s-i*c[pos],full&&(i==en));
if(!full)//不是边界,就记录,以防重复相同步骤,造成时间浪费
return dp[pos][s]=ans;
return ans;
}
2.枚举集合S的所有子集
例子:uva11825
for(i=1;i<(1<<n);i++)
{
dp[i]=0;
for(j=i;j;j=(j-1)&i)//枚举i的所有子集j
{
if(b[j]==all)
dp[i]=max(dp[i],dp[i^j]+1);
}
}
3.求两个需要优化的量v1和v2
例子:uva10859
要求首先满足v1最小,在v1相同的情况下v2最小,则可以把两者组合成一个量x=M*v1+v2,其中M是一个比“v2的最大理论值和v2的最小理论值之差”还大的数。这样,只要两个解得v1不同,则不管v2相差多少,都是v1其决定性作用;只有当v1相同时,才取决于v2。我们要求的就是最小的x,结果中v1=x/M,v2=x%M。
4.邻接表的添加和遍历
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <cctype>
using namespace std;
const int maxn=1e3+10;
struct node{ //邻接表结构体
int to,next;
}e[maxn];
int head[maxn],tt;
void init()//邻接表初始化
{
memset(head,-1,sizeof(head));
tt=0;
}
void add(int x,int y) //邻接表添加;
{
e[tt].to=y;
e[tt].next=head[x];
head[x]=tt++;
}
void print(int n) //邻接表输出
{
for(int u=0;u<n;u++)
{
for(int i=head[u];i!=-1;i=e[i].next)
{
printf("**%d %d\n",u,e[i].to);
}
}
}
int main()
{
init();
int n,x,y;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d%d",&x,&y);
add(x,y);
}
print(n);
return 0;
}
/*
3
0 1
0 2
1 2
*/
5.自定义的map
struct Map{
int head[maxn],next[maxn],key[maxn],val[maxn],tt;
Map(){tt=0;}
void clear()
{
memset(head,-1,sizeof(head));
tt=0;
}
int &get(int v)
{
int i,j,k,u=v%maxn;
for(i=head[u];i!=-1;i=next[i])
if(key[i]==v)return val[i];
key[tt]=v;
val[tt]=0;
next[tt]=head[u];
head[u]=tt;
return val[tt++];
}
int get2(int v)
{
int i,j,k,u=v%maxn;
for(i=head[u];i!=-1;i=next[i])
if(key[i]==v)return val[i];
return 0;
}
}mm;