UVALive - 6952 DP 分段/隔板

题意:商品总价按四舍五入计算,n个物品最多可分\(d+1\)段,求最小代价

\(dp[i][j]\):\(j\)个物品分\(i\)段

注意一个技巧是只在需要分出新的段时才四舍五入(旧段结算),这样就避免了不知道分段具体位置无法\(dp\)的情况

数据量比较小就不使用滚动数组了

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<string>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<map>
#define rep(i,j,k) for(register int i=j;i<=k;i++)
#define rrep(i,j,k) for(register int i=j;i>=k;i--)
#define erep(i,u) for(register int i=head[u];~i;i=nxt[i])
#define iin(a) scanf("%d",&a)
#define lin(a) scanf("%lld",&a)
#define din(a) scanf("%lf",&a)
#define s0(a) scanf("%s",a)
#define s1(a) scanf("%s",a+1)
#define print(a) printf("%lld",(ll)a)
#define enter putchar(‘\n‘)
#define blank putchar(‘ ‘)
#define println(a) printf("%lld\n",(ll)a)
#define IOS ios::sync_with_stdio(0)
using namespace std;
const int maxn = 1e5+11;
const int oo = 0x3f3f3f3f;
const double eps = 1e-7;
typedef long long ll;
ll read(){
    ll x=0,f=1;register char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
    return x*f;
}
ll dp[22][maxn],p[maxn];
int n,d;
inline ll cal(ll x){
    return (x+5)/10*10;
}
int main(){
    while(cin>>n>>d){
        memset(dp,0x3f,sizeof dp);
        rep(i,1,n) p[i]=read();
        dp[1][1]=p[1];
        rep(i,2,n) dp[1][i]=dp[1][i-1]+p[i];
        rep(i,2,d+1){
            rep(j,i,n){
                dp[i][j]=min(cal(dp[i-1][j-1])+p[j],dp[i][j-1]+p[j]);
            }
        }
        ll ans=oo;
        rep(i,1,d+1) ans=min(ans,cal(dp[i][n]));
        println(ans);
    }
    return 0;
} 

原文地址:https://www.cnblogs.com/caturra/p/8527450.html

时间: 2024-10-09 07:24:34

UVALive - 6952 DP 分段/隔板的相关文章

UVALive 4731 dp+贪心

这个题首先要利用题目的特性,先贪心,否则无法进行DP 因为求期望的话,越后面的乘的越大,所以为了得到最小值,应该把概率值降序排序,把大的数跟小的系数相乘 然后这种dp的特性就是转移的时候,由 i推到i+1每次添加一个数,就要考虑这个新数应该和谁放在一组,枚举他放在哪一组即可 dp[i][j]代表当前第i个数有j个分组时候的最小值 dp[i][j]=dp[k][j-1]+i(prefix[i]-prefix[k-1]),k代表枚举第几个数开始和当前新添加的数为一组,prefix为前缀和,为了迅速得

UVALive 4764 dp

DES: 这是一个新的游戏.给你一套牌.编号从1到100000.正常来说.你手中的牌和这次翻的牌是一样的,就会加一分.但是.如果是999的话.加三分.所以问你最大的分是多少. 貌似是简单的DP吧.(DP菜鸟...再简单我也不会...T_T...)于是...我看懂了...但是不可言传....~~~~(>_<)~~~~好难的好吗... #include<stdio.h> #include<string.h> #include<iostream> using na

uvalive 4256(dp)

题意:有从1到n的数字组成一个无向连通图,给出了连通情况,然后给出一个数字序列,问这个序列要求相邻的点要么相等要么在图中是直接连通的,问最少修改序列中的几个点可以让序列满足要求. 题解:f[i][j]表示前i个数组组成的序列以数字j结尾的最少修改点,那么f[i][j] = min{f[i][j],f[i - 1][k] + (d[i] != j)},此时j==k或g[j][k] == 1.最后f[len][k]所有数字过一遍选出最大值就可以了. #include <stdio.h> #incl

POJ 3486 &amp;amp; HDU 1913 Computers(dp)

题目链接:PKU:HDU: PKU:http://poj.org/problem?id=3486 HDU:pid=1913" target="_blank">http://acm.hdu.edu.cn/showproblem.php?pid=1913 Description Everybody is fond of computers, but buying a new one is always a money challenge. Fortunately, ther

POJ 3486 &amp; HDU 1913 Computers(dp)

题目链接:PKU:HDU: PKU:http://poj.org/problem?id=3486 HDU:http://acm.hdu.edu.cn/showproblem.php?pid=1913 Description Everybody is fond of computers, but buying a new one is always a money challenge. Fortunately, there is always a convenient way to deal wi

UOJ#110. 【APIO2015】Bali Sculptures

印尼巴厘岛的公路上有许多的雕塑,我们来关注它的一条主干道. 在这条主干道上一共有 NN 座雕塑,为方便起见,我们把这些雕塑从 11 到 NN 连续地进行标号,其中第 ii 座雕塑的年龄是 YiYi 年.为了使这条路的环境更加优美,政府想把这些雕塑分成若干组,并通过在组与组之间种上一些树,来吸引更多的游客来巴厘岛. 下面是将雕塑分组的规则: 这些雕塑必须被分为恰好 XX 组,其中 A≤X≤BA≤X≤B,每组必须含有至少一个雕塑,每个雕塑也必须属于且只属于一个组.同一组中的所有雕塑必须位于这条路的连

hdu_5807_Keep In Touch(分段dp)

题目链接:hdu_5807_Keep In Touch 题意: 在Byteland一共有nn个城市,编号依次为11到nn,同时有mm条单向道路连接着这些城市,其中第ii条道路的起点为u_iu?i??,终点为v_i(1\leq u_i < v_i\leq n)v?i??(1≤u?i??<v?i??≤n). 特工团队一共有33名成员:007,008,以及009,他们将要执行qq次秘密任务. 在每次任务中,三人可能会处于三个不同的城市,他们互相之间通过对讲机保持联络.编号为ii的城市的无线电频为w_

DP UVALive 6506 Padovan Sequence

题目传送门 /* 题意:两行数字,相邻列一上一下,或者隔一列两行都可以,从左到右选择数字使和最大 DP:状态转移方程:dp[i][j] = max (dp[i][j], dp[1-i][j-1] + a[i][j], dp[i/1-i][j-2] + a[i][j]); 要从前面一个转态推过来啊,我比赛写反了,内功不够:( */ #include <cstdio> #include <algorithm> #include <iostream> #include <

UVALive 3942 - Remember the Word(DP,数组Trie+指针Trie)

UVALive 3942 - Remember the Word(DP,数组Trie+指针Trie) ACM 题目地址: UVALive 3942 - Remember the Word 题意: 给一些单词,然后给一个长的单词,问有几种方法能组成这个大单词,单词可以重复用. 分析: DP[i]=sum{DP[j} (i<j<len),从后往前求. 本来用数组Trie写得爽爽的,1A了. 发现2s多,不能忍! 然后用指针Trie写了一遍,各种出错,整个人都不好了... 研究了一遍别人代码,发现快