zoukankan      html  css  js  c++  java
  • 【CF 189A Cut Ribbon】dp

    题目链接:http://codeforces.com/problemset/problem/189/A

    题意:一个长度为n的纸带,允许切割若干次,每次切下的长度只能是{a, b, c}之一。问最多能切成多少块。

    思路:动态规划,记dp[i] 为当前已经切下总长度 i 时最多能切成的块数,即规模为 i 的子问题。

    状态的转移比较好想,每次只可能从dp[i-a], dp[i-b], dp[i-c]三个方向通过加一转移过来。

    问题的初始化我考虑得有点复杂:先把a, b, c从小到大排序,然后对于 i 属于[0, a), [a, b), [b, c]三个区间按顺序初始化dp[i]:判断 i 能否分解成{a}, {a, b}, {a, b, c}的“线性组合”,可以的话取系数和最大的那个作为dp[i]。

    初始化之后就是线性的从[c, n]的枚举,每次取三个转移方向中最优的那个。

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <cstring>
     4 #include <string>
     5 #include <cstdlib>
     6 #include <cctype>
     7 #include <cmath>
     8 #include <algorithm>
     9 #include <vector>
    10 #include <map>
    11 #include <set>
    12 #include <stack>
    13 #include <queue>
    14 #include <assert.h>
    15 #define FREAD(fn) freopen((fn), "r", stdin)
    16 #define RINT(vn) scanf("%d", &(vn))
    17 #define PINT(vb) printf("%d", vb)
    18 #define RSTR(vn) scanf("%s", (vn))
    19 #define PSTR(vn) printf("%s", (vn))
    20 #define CLEAR(A, X) memset(A, X, sizeof(A))
    21 #define REP(N) for(i=0; i<(N); i++)
    22 #define REPE(N) for(i=1; i<=(N); i++)
    23 #define pb(X) push_back(X)
    24 #define pn() printf("
    ")
    25 using namespace std;
    26 const int MAX_N = 4005;
    27 int i, j;
    28 int n, a, b, c;
    29 int dp[MAX_N];//dp[i]=总长度为i时能切成的最大块数
    30 
    31 int main()
    32 {
    33     CLEAR(dp, 0);
    34     RINT(n);
    35     RINT(a); RINT(b); RINT(c);
    36     if(a > b) swap(a, b);
    37     if(b > c) swap(b, c);
    38     for(i=0; i<a; i++)
    39         dp[i] = 0;
    40     for(i=a; i<b; i++){
    41         if(i % a == 0) dp[i] = i/a;
    42         else dp[i] = 0;
    43     }
    44     for(i=b; i<=c; i++){
    45         if(i % a == 0){
    46             dp[i] = i/a;
    47             continue;
    48         }
    49         else{
    50             bool flag = 0;
    51             for(j=0; j*a < i; j++){
    52                 if((i-j*a) % b == 0){
    53                     flag = 1;
    54                     dp[i] = max(dp[i], j + (i-j*a)/b);
    55                 }
    56             }
    57             if(flag) continue;
    58         }
    59         if(i % b == 0) dp[i] = max(dp[i], i/b);
    60         else if(i == c) dp[i] = max(dp[i], 1);
    61         else dp[i] = 0;
    62     }
    63     //printf("dp[%d] = %d
    ", b, dp[b]);
    64     for(i=c; i<=n; i++){
    65         if(dp[i-a] > 0) 
    66             dp[i] = max(dp[i], dp[i-a] + 1);
    67         if(dp[i-b] > 0)
    68             dp[i] = max(dp[i], dp[i-b] + 1);
    69         if(dp[i-c] > 0)
    70             dp[i] = max(dp[i], dp[i-c] + 1);
    71     }
    72     // REP(n) 
    73     //     printf("dp[%d]  = %d
    ", i, dp[i]);
    74     PINT(dp[n]);
    75     return 0;
    76 }
  • 相关阅读:
    项目中 2个或者多个EF模型 表名称相同会导致生成的实体类 覆盖的解决方法
    Validation failed for one or more entities. See ‘EntityValidationErrors’解决方法;关于如何查看 EntityValidationErrors 详细信息的解决方法
    深夜杳杳
    我在学习
    IIS下新建虚拟目录
    Win10资源管理器异常
    Docker笔记三:Docker数据卷和DockerFile
    Docker笔记二:Docker拷贝,提交,进入容器和阿里云加速
    ElasticSearch7.x系列三:Logstash的使用
    ElasticSearch7.x系列二:Kibana的使用和C#的Nest客户端
  • 原文地址:https://www.cnblogs.com/helenawang/p/5627070.html
Copyright © 2011-2022 走看看