算法竞赛进阶指南 0x50 动态规划

 算法竞赛进阶指南 0x50 动态规划

该书的数学知识,竟然下不了手,那么好吧,至少要AC一道,从动态规划开始吧,多少有一定积累2018-2-13 10:04

http://begin.lydsy.com/JudgeOnline/problemset.php?page=38

0x51 线性DP

//4854: Poj2279 Mr. Young's Picture Permutations
//看了书中光盘的代码,发现量有些大,决定还是研究短代码
//https://www.cnblogs.com/five20/p/8530611.html此文介绍得不错
//但有一个问题,杨氏矩阵,是递增的,该题是递减的,如何转换

//对文中例子进行模拟 2018-3-12

算法竞赛进阶指南 0x50 动态规划_第1张图片
//采用勾长公式处理该题
//https://vjudge.net/problem/POJ-2279可见该题
//样例通过,提交AC 2018-3-12 17:30  
#include
#include
#define LL long long
int row[10];//此处写成int row[10],sum[40];
LL sum[200];
LL gcd(LL a,LL b){
    return b?gcd(b,a%b):a;
}
int main(){
    int n,i,j,k,cnt;//n表示行数,cnt统计人数
    LL a,b,d;
    while(scanf("%d",&n)&&n){
        a=1,b=1,d=1,cnt=0,memset(sum,0,sizeof(sum));//漏了cnt=0这句//sum[i] i人对应的勾长
        for(i=1;i<=n;i++)scanf("%d",&row[i]);//row[i] i行人数
        for(i=1;i<=n;i++)//行
            for(j=1;j<=row[i];j++){//列
                cnt++;
                for(k=i+1;k<=n;k++)//此处写成for(k=j+1;k<=n;k++)//处理j列 下面数据
                    if(j<=row[k])sum[cnt]++;//j下面有数据
                    else break;//不用循环了,没有此句,也可以
                sum[cnt]+=row[i]-j+1;//处理j行 右边数据
                
            }
        for(i=1;i<=cnt;i++){
            a*=i,b*=sum[i];
            d=gcd(a,b),a/=d,b/=d;
        }
        printf("%lld\n",a/b);
    }
    return 0;
}


0x52 背包

//4860: 数字组合
//01背包问题
//看了数据范围,N(1//该题一上手,就是一个相对复杂的01背包计数问题。
//样例通过,提交AC 2018-2-13 10:47
//该书,本人 第一道AC 的题 万事开头难,一个好的开始
#include
#include
int f[10100],a[110];
int main(){
    int n,m,i,j;
    memset(f,0,sizeof(f));
    scanf("%d%d",&n,&m);
    for(i=1;i<=n;i++)scanf("%d",&a[i]);
    f[0]=1;//做多了,该初始化也就不难了
    for(i=1;i<=n;i++)
        for(j=m;j>=a[i];j--)
            f[j]+=f[j-a[i]];
    printf("%d",f[m]);
    return 0;
}
//4861: 自然数拆分Lunatic版
//参与加法运算的数可以重复,完全背包问题
//同样属于较难的计数问题,编写下来,一直 比样例结果多了1
//很是奇怪,f[1]=1 1=1,f[2]=2 2=1+1 2=2,f[3]=3 3=1+1+1 3=1+2 3=3
//重读题目,发现,题中要求 拆分成由若干数相加的形式
//故上述应改成 f[1]=0,f[2]=1 2=1+1 f[3]=2 1+1+1 f[3]=1+2
//修改代码,即i<=n改成i//一直隐隐的觉得 2147483648 超出了int 范围,计算 2^31-1= 2147483647
//果断将 int f[4100]改成 long long f[4100]
//提交AC,好高兴啊,没有参考任何东西,完全是自己独立思考的结果,确实水平实实在在的进步。2018-2-13 16:49
#include
#include
#define mod 2147483648
long long f[4100];//此处写成 int f[4100];
int main(){
    int n,i,j;
    memset(f,0,sizeof(f));
    scanf("%d",&n);
    f[0]=1;//多写多编,该初始化很快就能理解
    for(i=1;i        for(j=i;j<=n;j++)
            f[j]=(f[j]+f[j-i])%mod;
    printf("%lld",f[n]);//此处写成 printf("%d",f[n]);
    return 0;
}


0x53 区间DP

0x54 树形DP

0x55 环状与后效性处理

0x56 状态压缩DP

0x57 倍增优化DP

0x58 数据结构优化DP

0x59 单调队列优化DP

0x5A 斜率优化

0x5B 四边形不等式

0x5C 计数类DP

0x5D 数位统计DP

0x5E 总结与练习


你可能感兴趣的:(算法竞赛进阶指南)