zoukankan      html  css  js  c++  java
  • 让人难以想出的动态转移方程小集

    总有一些动态转移方程让人很难想,现在先让我们看几道题吧。

    1.luoguP4138 [JOISC2014]挂饰:

    题目描述

    JOI君有N个装在手机上的挂饰,编号为1...N。 JOI君可以将其中的一些装在手机上。

    JOI君的挂饰有一些与众不同——其中的一些挂饰附有可以挂其他挂件的挂钩。每个挂件要么直接挂在手机上,要么挂在其他挂件的挂钩上。直接挂在手机上的挂件最多有1个。

    此外,每个挂件有一个安装时会获得的喜悦值,用一个整数来表示。如果JOI君很讨厌某个挂饰,那么这个挂饰的喜悦值就是一个负数。

    JOI君想要最大化所有挂饰的喜悦值之和。注意不必要将所有的挂钩都挂上挂饰,而且一个都不挂也是可以的。

    输入格式

    第一行一个整数N,代表挂饰的个数。

    接下来N行,第i行(1<=i<=N)有两个空格分隔的整数Ai和Bi,表示挂饰i有Ai个挂钩,安装后会获得Bi的喜悦值。

    输出格式

    输出一行一个整数,表示手机上连接的挂饰总和的最大值

    输入输出样例

    输入 #1
    5
    0 4
    2 -2
    1 -1
    0 1
    0 3
    输出 #1
    5

    说明/提示

    ≤ ≤ 2000

    ≤ A≤ (1iN)

    10^6 ≤ B≤ 10^(1iN)

    f[ i ] [ j ]表示前i件物品在有j个挂钩的情况下的最大价值

    因为j-w[i]+1可能是个负数,没有意义,这时候就要考虑这物品直接挂在手机上即j=1,也就需要我们把j-w[i]和0取最大值保证有意义

    所以正解方程为f[i][j]=max(f[i-1][j],f[i-1][max(j-w[i].a,0)+1]+w[i].b)  ;//这里的a是钩子,b是价值

    注意:这里的 j 是指剩余的挂钩数量。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 #include <cmath>
     5 
     6 #define maxn 3100
     7 #define maxx -1000000000
     8 using namespace std;
     9 int f[maxn][maxn];
    10 struct node{
    11     int a,b;
    12 }a[maxn];
    13 bool cmp(node a,node b){
    14     return a.a>b.a;
    15 }
    16 int main(){
    17     int n;
    18     cin>>n;
    19     for(int i = 1; i <= n; i++){
    20     cin>>a[i].a>>a[i].b;    
    21     }
    22     sort(a+1,a+1+n,cmp);
    23     for(int i = 0; i<= n; i++){
    24         f[i][n+1]=maxx;
    25         f[0][i]=maxx;//初始化要注意
    26     }
    27     f[0][1]=0;
    28     for(int i = 1 ;i <= n; i++){
    29         for(int j =0 ; j <= n; j++){
    30             f[i][j]=max(f[i-1][j],f[i-1][max(j-a[i].a,0)+1]+a[i].b);
    31         }
    32     }
    33     int maxm=maxx;
    34     for(int i = 0 ; i<= n; i++){
    35         maxm=max(maxm,f[n][i]);
    36     }
    37     cout<<maxm;
    38     return 0;
    39 } 

    2.luoguP1412 经营与开发 

    你驾驶着一台带有钻头(初始能力值w)的飞船,按既定路线依次飞过n个星球。

    星球笼统的分为2类:资源型和维修型。(p为钻头当前能力值)

    1.资源型:含矿物质量a[i],若选择开采,则得到a[i]*p的金钱,之后钻头损耗k%,即p=p*(1-0.01k)

    2.维修型:维护费用b[i],若选择维修,则支付b[i]*p的金钱,之后钻头修复c%,即p=p*(1+0.01c)

    注:维修后钻头的能力值可以超过初始值(你可以认为是翻修+升级)

    金钱可以透支。

    请作为舰长的你仔细抉择以最大化收入。

    输入格式

    第一行4个整数n,k,c,w。

    以下n行,每行2个整数type,x。

    type为1则代表其为资源型星球,x为其矿物质含量a[i];

    type为2则代表其为维修型星球,x为其维护费用b[i];

    输出格式

    一个实数(保留2位小数),表示最大的收入。

    输入输出样例

    输入 #1
    5 50 50 10
    1 10
    1 20
    2 10
    2 20
    1 30
    
    输出 #1
    375.00

    说明/提示

    【数据范围】

    对于30%的数据 n<=100

    另有20%的数据 n<=1000;k=100

    对于100%的数据 n<=100000; 0<=k,c,w,a[i],b[i]<=100;保证答案不超过10^9

     1 #include <iostream>
     2 #include <cstdio>
     3 using namespace std;
     4 int n, f[100005], a[100005];
     5 double c, k, w, dp[100005];
     6 int main(){
     7     cin>>n>>k>>c>>w;
     8     for(int i=1; i<=n; i++)
     9         scanf("%d %d", &f[i], &a[i]);
    10     for(int i=n; i>=1; i--){
    11         if(f[i]==1)    dp[i] = max(dp[i+1], a[i]+dp[i+1]*(1-0.01*k));
    12         else        dp[i] = max(dp[i+1], -a[i]+dp[i+1]*(1+0.01*c));
    13     }
    14     printf("%.2lf", dp[1]*w);
    15     return 0;
    16 }
  • 相关阅读:
    使用Angular CLI生成 Angular 5项目
    asp.net core 2.0 web api + Identity Server 4 + angular 5 可运行前后台源码
    依赖反转原则DIP 与使用了Repository模式的asp.net core项目结构
    Git基本命令 -- 别名 + 忽略 + 推送
    Git基本命令 -- 历史
    多线程,论多核时代爱恨情仇
    凛冬将至,用几款特效暖暖身
    HTML5游戏开发引擎,初识CreateJS
    详解设计模式之工厂模式(简单工厂+工厂方法+抽象工厂)
    详解设计模式六大原则
  • 原文地址:https://www.cnblogs.com/becase/p/11847062.html
Copyright © 2011-2022 走看看