DP专题考试总结(4)

最近努力学(tui)习(fei)了DP专题,然后考试又挂了,然后就没有然后了。
对此,我只想说——
吾每念,常痛于骨髓,顾计不知所出耳!


广场铺砖问题

期望得分:40
实际得分:10
Description
有一个 W行 H列的广场,需要用 1*2小砖铺盖,小砖之间互相不能重叠,问
有多少种不同的铺法?
Date Size
1<=W,H<=11
Solution
这是一道状压DP中的水题。我难道会告诉你我跳了状态压缩DP吗
于是乎,自顾自的打了40分的暴力走人。
可以按行枚举,有三种选择:①空着②摆一个横的③摆一个占用上一行的竖的
但第一行没有③选项,那么就把第一行处理成全摆满的情况。
然后开始愉快地状态DP。
Code

#include 
#include 
using namespace std;
int n,m;
long long f[12][(1<<12)];
void dfs(int h,int l,int now,int pre)
{
    if(l>m+1)
      return ;
    if(l==m+1)
    {
        f[h][now]+=f[h-1][pre];
        return ;
    }
    dfs(h,l+1,now<<1,(pre<<1)|1);//1情况
    dfs(h,l+2,(now<<2)|3,(pre<<2)|3);//2情况
    dfs(h,l+1,(now<<1)|1,pre<<1);//③情况
}
int main()
{
    scanf("%d %d",&n,&m);
    f[0][(1<1]=1;
    for(int i=1;i<=n;i++)
      dfs(i,1,0,0);
    printf("%lld\n",f[n][(1<1]);
    return 0;
}

选课

Description
略(就是平常的选课题面,只不过要求输出最优方案)
Date Size
课程数<=500
Solution
看到这道题目的时候超惊喜的有没有,哇,竟然良心地考原题水题,超感动的有没有。愉快地打了树形DP,满心欢喜地以为AC了,开始测样例,然后突然发现要输出最优方案。于是乎,就挂了。
kb用的是DP两次,第一次跑答案,第二次利用答案跑方案,当然第二次的重复计算可以使用第一次跑出来的数据。不过按kb的说法是,更优的方案应该是,多叉树转二叉树,这样更好记录答案,然后排序输出就好了。

卡车更新问题

Description
某人购置了一辆新卡车, 从事个体运输业务. 给定以下各有关数据:
R[t], t=0,1,2,…,k, 表示已使用过 t 年的卡车, 再工作一年所得的运费, 它随 t 的增加而减少, k (k 年后卡车已无使用价值)。
U[t]: t=0,1,…,k, 表示已使用过 t 年的卡车, 再工作一年所需的维修费, 它随 t 的增加而增加.
C[t], t=0,1,2,…,k, 表示已使用过 t 年的旧卡车, 卖掉旧车, 买进新车, 所需的净费用, 它随 t 的增加而增加. 以上各数据均为实型, 单位为”万元”.
设某卡车已使用过 t 年,
① 如果继续使用, 则第 t+1 年回收额为 R[t]-U[t],
② 如果卖掉旧车,买进新车, 则 第 t+1年回收额为 R[0]-U[0]-C[t] .
该运输户从某年初购车日起,计划工作 N (N<=20) 年, N 年后不论车的状态如何,不再工作. 为使这 N 年的总回收额最大, 应在哪些年更新旧车? 假定在这 N 年内, 运输户每年只用一辆车, 而且以上各种费用均不改变.
Date Size
k<=20
Solution
好像是一道比较裸又比较水的DP,也没有什么好解释的,就直接上代码好了。
Code

#include 
#include 
#include 
using namespace std;
const double eps=1e-10;
int n,k;
double ans=0,r[22],u[22],c[22],f[22][22];
void print(int x,int y){
    double kl;
    int i,j;
    if(x==1)
    {
        printf("%d 0 %.1lf\n",x,f[x][0]);
        return;
    }
    if(y==0)
      for(i=0;i1&&iif(fabs(f[x-1][i]+r[0]-u[0]-c[i+1]-f[x][y])1,i);printf("%d 1 %.1lf\n",x,f[x][y]-f[x-1][i]);
          return;
        }
    print(x-1,y-1);
    printf("%d 0 %.1lf\n",x,f[x][y]-f[x-1][y-1]);
}
int main()
{
    freopen("truck.in","r",stdin);
    freopen("truck.out","w",stdout);
    int flag;
    scanf("%d%d",&n,&k);
    for(int i=0;i<=k;i++)
      scanf("%lf",&r[i]);
    for(int i=0;i<=k;i++)
      scanf("%lf",&u[i]);
    for(int i=0;i<=k;i++)
      scanf("%lf",&c[i]);
    f[1][0]=r[0]-u[0];
    for(int i=2;i<=n;i++)
    {
        f[i][0]=f[i-1][0]+r[0]-u[0]-c[1];
        for(int j=1;j1&&j0]=max(f[i][0],f[i-1][j]+r[0]-u[0]-c[j+1]);
        for(int j=1;j1][j-1]+r[j]-u[j];
    }
    for(int i=0;iif(f[n][i]>ans)
        ans=f[n][i],flag=i;
    printf("%.1lf\n",ans);
    print(n,flag);
    return 0;
}

你可能感兴趣的:(=====动态规划=====)