题目链接: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]的枚举,每次取三个转移方向中最优的那个。

 #include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <assert.h>
#define FREAD(fn) freopen((fn), "r", stdin)
#define RINT(vn) scanf("%d", &(vn))
#define PINT(vb) printf("%d", vb)
#define RSTR(vn) scanf("%s", (vn))
#define PSTR(vn) printf("%s", (vn))
#define CLEAR(A, X) memset(A, X, sizeof(A))
#define REP(N) for(i=0; i<(N); i++)
#define REPE(N) for(i=1; i<=(N); i++)
#define pb(X) push_back(X)
#define pn() printf("\n")
using namespace std;
const int MAX_N = ;
int i, j;
int n, a, b, c;
int dp[MAX_N];//dp[i]=总长度为i时能切成的最大块数 int main()
{
CLEAR(dp, );
RINT(n);
RINT(a); RINT(b); RINT(c);
if(a > b) swap(a, b);
if(b > c) swap(b, c);
for(i=; i<a; i++)
dp[i] = ;
for(i=a; i<b; i++){
if(i % a == ) dp[i] = i/a;
else dp[i] = ;
}
for(i=b; i<=c; i++){
if(i % a == ){
dp[i] = i/a;
continue;
}
else{
bool flag = ;
for(j=; j*a < i; j++){
if((i-j*a) % b == ){
flag = ;
dp[i] = max(dp[i], j + (i-j*a)/b);
}
}
if(flag) continue;
}
if(i % b == ) dp[i] = max(dp[i], i/b);
else if(i == c) dp[i] = max(dp[i], );
else dp[i] = ;
}
//printf("dp[%d] = %d\n", b, dp[b]);
for(i=c; i<=n; i++){
if(dp[i-a] > )
dp[i] = max(dp[i], dp[i-a] + );
if(dp[i-b] > )
dp[i] = max(dp[i], dp[i-b] + );
if(dp[i-c] > )
dp[i] = max(dp[i], dp[i-c] + );
}
// REP(n)
// printf("dp[%d] = %d\n", i, dp[i]);
PINT(dp[n]);
return ;
}

【CF 189A Cut Ribbon】dp的更多相关文章

  1. CF 189A Cut Ribbon

    #include<bits/stdc++.h> using namespace std; const int maxn = 4000 + 131; int n, a, b, c; int ...

  2. B. Lost Number【CF交互题 暴力】

    B. Lost Number[CF交互题 暴力] This is an interactive problem. Remember to flush your output while communi ...

  3. Codeforces Round #119 (Div. 2) Cut Ribbon(DP)

    Cut Ribbon time limit per test 1 second memory limit per test 256 megabytes input standard input out ...

  4. 3.26-3.31【cf补题+其他】

      计蒜客)翻硬币 //暴力匹配 #include<cstdio> #include<cstring> #define CLR(a, b) memset((a), (b), s ...

  5. 【cf补题记录】Codeforces Round #608 (Div. 2)

    比赛传送门 再次改下写博客的格式,以锻炼自己码字能力 A. Suits 题意:有四种材料,第一套西装需要 \(a\).\(d\) 各一件,卖 \(e\) 块:第二套西装需要 \(b\).\(c\).\ ...

  6. 【CF 675D Tree Construction】BST

    题目链接:http://codeforces.com/problemset/problem/675/D 题意:给一个由n个互异整数组成的序列a[],模拟BST的插入过程,依次输出每插入一个元素a[i] ...

  7. Codeforces 189A. Cut Ribbon

    题目链接:http://codeforces.com/problemset/problem/189/A 题意: 给你一个长度为 N 的布条, 再给你三个长度 a, b , c.你可以用剪刀去剪这些布条 ...

  8. 【最大M子段和】dp + 滚动数组

    题目描述 给定 n 个数求这 n 个数划分成互不相交的 m 段的最大 m 子段和. 给出一段整数序列 A1,A2,A3,A4,...,Ax,...,An ,其中 1≤x≤n≤1,000,000, -3 ...

  9. BZOJ2555 SubString【SAM + Link Cut Tree】

    BZOJ2555. SubString 要求在线询问一个串在原串中出现的次数,并且可以在原串末尾添加字符串 如果没有修改的话,考虑建出\(parent\)树之后统计每个\(endpos\)节点的\(r ...

随机推荐

  1. 【剑指offer】面试题39:二叉树的深度

    题目: 输入一棵二叉树,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长度为树的深度. 思路: 根的深度=MAX(左子树深度,右子树深度)+1; Code: ...

  2. Mybatis 开发中遇见的异常及处理

    1 异常信息: org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.binding.Bin ...

  3. python3-day3(函数-参数)

    1.参数 函数的核心是参数传值,其次是返回值,熟练这两这个技术即可灵活使用函数. 1>普通参数 def  show(name): print(name) show('tom') 2>默认参 ...

  4. DDMS files not found: tools\hprof-conv.exe

    最近在Eclipse下每次更新ADT和SDK后都报一些错误,比如 DDMS files not found: D:\android-sdk-windows-1.6_r1\android-sdk-win ...

  5. LNMP、LAMP、LANMP一键安装脚本(定期更新)[转]

    这个脚本是使用shell编写,为了快速在生产环境上部署LNMP/LAMP/LANMP(Linux.Nginx/Tengine.MySQL/MariaDB/Percona.PHP),适用于CentOS/ ...

  6. Activity中的startActivityResult,setResult,finish,onActivityResult的关系

    一:首先图示: 二:代码: 1:方法selectName public void selectName(View view){ Intent intent = new Intent(this,Name ...

  7. IPMITOOL常用操作指令

    一.开关机,重启 1. 查看开关机状态: ipmitool -H (BMC的管理IP地址) -I lanplus -U (BMC登录用户名) -P (BMC 登录用户名的密码) power statu ...

  8. js_day14

  9. exec与xargs区别

    区别描述: 两者都是对符合条件的文件执行所给的Linux 命令,而不询问用户是否需要执行该命令. -exec:{}表示命令的参数即为所找到的文件,以:表示comman命令的结束.\是转义符,因为分号在 ...

  10. windows服务器性能监控工具、方法及关键指标

    原文:http://www.cnblogs.com/liulun/p/3543777.html 监控方法 推荐使用windows自带的“性能监视器”(老版本的windows叫性能计数器)来监控服务器的 ...