【CF 189A Cut Ribbon】dp

简介: 题目链接:http://codeforces.com/problemset/problem/189/A 题意:一个长度为n的纸带,允许切割若干次,每次切下的长度只能是{a, b, c}之一。问最多能切成多少块。

题目链接: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("\n")
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\n", 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\n", i, dp[i]);
74     PINT(dp[n]);
75     return 0;
76 }

 

目录
相关文章
|
7月前
|
机器学习/深度学习
CF189A Cut Ribbon(dp一维思想,完全背包最详细解析)
CF189A Cut Ribbon(dp一维思想,完全背包最详细解析)
50 0
|
4月前
|
JSON 负载均衡 Java
Spring Cloud Ribbon:负载均衡的服务调用
Spring Cloud Ribbon:负载均衡的服务调用
64 0
|
6月前
|
负载均衡
09SpringCloud - Ribbon项目示例
09SpringCloud - Ribbon项目示例
18 0
|
7月前
|
开发框架 负载均衡 Java
Spring Cloud 介绍及负载均衡Ribbon、服务容错Hystrix 组件使用详解
Spring Cloud 介绍及负载均衡Ribbon、服务容错Hystrix 组件使用详解
115 0
|
29天前
|
负载均衡 算法 Java
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(四)Ribbon的使用
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(四)Ribbon的使用
23 0
|
1月前
|
负载均衡
【二十】搭建SpringCloud项目四(Ribbon)
【二十】搭建SpringCloud项目四(Ribbon)
19 0
|
1月前
|
存储 负载均衡 Java
【Spring底层原理高级进阶】微服务 Spring Cloud 的注册发现机制:Eureka 的架构设计、服务注册与发现的实现原理,深入掌握 Ribbon 和 Feign 的用法 ️
【Spring底层原理高级进阶】微服务 Spring Cloud 的注册发现机制:Eureka 的架构设计、服务注册与发现的实现原理,深入掌握 Ribbon 和 Feign 的用法 ️
|
1月前
|
负载均衡 算法 Java
SpringCloud负载均衡源码解析 | 带你从表层一步步剖析Ribbon组件如何实现负载均衡功能
SpringCloud负载均衡源码解析 | 带你从表层一步步剖析Ribbon组件如何实现负载均衡功能
|
3月前
|
负载均衡 Java 应用服务中间件
springcloud3-服务到服务调用ribbon及openfeign
springcloud3-服务到服务调用ribbon及openfeign
43 0
|
3月前
|
存储 负载均衡 算法
spring cloud 之 Ribbon
spring cloud 之 Ribbon
49 0