Codeforces Round #145 (Div. 1, ACM-ICPC Rules)B dp

///dp[i][j][0] 表示前i列涂了j个red且第j列是red得到最少的valul

//dp[i][j][1]表示第i列涂了j个red且第j列是green得到的最少的value

//dp[i][j][0] = min(dp[i-1][j-h[i]][0] , dp[i][j][1] + min(h[i-1] ,h[i]))

//dp[i][j][1] = min(dp[i-1][j][0] + min(h[i-1],h[i]) ,dp[i][j][1])

#include<cstdio>

#include<cstring>

#include<iostream>

using namespace std ;

const int inf = 0x3f3f3f3f;

const int maxn  = 210 ;

int dp[maxn][maxn*maxn][2]; //dp[i][j][0] 表示第i列去了j个a且第j列是a得到最少的value

int sum[maxn];

int h[maxn];

int Min(int a ,int b)

{

if(a == -1)

return b;

if(b == -1)

return a;

return min(a,b);

}

int main()

{

freopen("input.txt","r",stdin);

freopen("output.txt","w",stdout);

int n , a, b;

while(~scanf("%d" ,&n))

{

scanf("%d%d" ,&a ,&b);

sum[0] = 0 ;

for(int i = 1;i <= n;i++)

scanf("%d" ,&h[i]) , sum[i]=sum[i-1]+h[i];

memset(dp , -1 , sizeof(dp));

if(h[1] <= a)

dp[1][h[1]][0] = 0;

if(h[1] <= b)

dp[1][0][1] = 0 ;

for(int i = 1;i < n;i++)

{

if(sum[i] <= b)

dp[i][0][1] = 0;

for(int j = 0;j <= a;j++)

{

if(dp[i][j][0] != -1)

{

if(j+h[i+1] <= a)

dp[i+1][j+h[i+1]][0] = Min(dp[i+1][j+h[i+1]][0] , dp[i][j][0]);

if(sum[i+1] - j <= b)

dp[i+1][j][1] = Min(dp[i+1][j][1] , dp[i][j][0] + min(h[i] ,h[i+1]));

}

if(dp[i][j][1] != -1)

{

if(j+h[i+1] <= a)

dp[i+1][j+h[i+1]][0] = Min(dp[i+1][j+h[i+1]][0] , dp[i][j][1] + min(h[i] ,h[i+1]));

if(sum[i+1] - j <= b)

dp[i+1][j][1] = Min(dp[i+1][j][1] , dp[i][j][1]);

}

}

}

int ans = inf ;

for(int i = 0;i <= a;i++)

ans = Min(Min(ans ,dp[n][i][0]) , dp[n][i][1]);

if(ans == inf)puts("-1");

else printf("%d\n",ans);

}

}

时间: 2024-12-16 21:43:45

Codeforces Round #145 (Div. 1, ACM-ICPC Rules)B dp的相关文章

codeforces水题100道 第十八题 Codeforces Round #289 (Div. 2, ACM ICPC Rules) A. Maximum in Table (brute force)

题目链接:http://www.codeforces.com/problemset/problem/509/A题意:f[i][1]=f[1][i]=1,f[i][j]=f[i-1][j]+f[i][j-1],求f[n][n].C++代码: #include <iostream> using namespace std; int n, f[11][11]; int main() { cin >> n; for (int i=1;i<=n;i++) f[i][1] = f[1][

Codeforces Round #289 (Div. 2, ACM ICPC Rules)——B贪心——Painting Pebbles

There are n piles of pebbles on the table, the i-th pile contains ai pebbles. Your task is to paint each pebble using one of the k given colors so that for each color c and any two piles i and j the difference between the number of pebbles of color c

Codeforces Round #289 (Div. 2, ACM ICPC Rules) (A, B, C, E)

A:水题,根据题目预处理一下输出即可 B:先把最大和最小找出来,可以让最小全是1,然后最大比最小多出的部分就放1,2,3,4,5...所以如果MAX - MIN > k就是NO,不然就根据这个构造出答案 C:贪心的策略,每次要让数字尽量小,那么就和上一个数字比较,如果需要的和比上一个小,就先找到一个新数字,使得和小于所需数字,并且该数字是大于上一个数字的最小值,找的方法就是从末尾不断放0进位.那么现在情况就只剩下需要的和比上一个大的了,这个就贪心,从末尾尽量变成9即可 E:一个计数问题,其实只要

Codeforces Round #289 (Div. 2, ACM ICPC Rules)

A题: 有一个n*n的矩阵,矩阵的第一行和第一列的值都为1,其余的有: a[i][j]=a[i-1][j]+a[i][j-1]; 现在给出一个n求出这个n*n的矩阵中最大的数. 显然,最大的数就是a[n][n]. 因为n<=10,所以先预处理出一个10*10的矩阵,然后每输入一个n,直接输出a[n][n]. 1 #include<cstdio> 2 int maze[11][11]; 3 int main() 4 { 5 for(int i=1;i<=10;i++) 6 maze[

Codeforces Round #417 (Div. 2) B. Sagheer, the Hausmeister(DP)

题目链接:Codeforces Round #417 (Div. 2) B. Sagheer, the Hausmeister 题意: 有n层楼,每层有m个房间,每层的两边是楼梯. 现在有一个人站在左下角,这个人必须将这一层的灯关闭后才能去另外一层. 每移动一次需要1分钟,问关闭所有灯需要多少时间. 题解: 考虑DP[i][j]表示当前已经关闭了第i层全部的灯,j=0时表示在这一层的最左边,j=1时表示在这一层的最右边. 然后推上去就行了.最后讨论一下特殊情况. 1 #include<bits/

Codeforces Round #360 (Div. 2) D 数学推导 E dp

Codeforces Round #360 (Div. 2) A  == B  水,但记一下: 第 n 个长度为偶数的回文数是  n+reverse(n). C    dfs 01染色,水 #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a; i<=b; ++i

Codeforces Round #145 (Div. 1, ACM-ICPC Rules)A

//记录每一个film的已经确定喜欢的数 //记录film最多有几个喜欢的明星数 //然后比较,如果对于这个film,它已经确定的喜欢的数大于等于其他的film的最多的喜欢的明星,那么0 //如果存在一个其他film已经确定的喜欢的数大于这个film最多喜欢的明星数,那么1 //其他2 #include<cstdio> #include<cstring> #include<iostream> using namespace std ; const int maxn  =

Codeforces Round #245 (Div. 1) B. Working out (简单DP)

题目链接:http://codeforces.com/problemset/problem/429/B 给你一个矩阵,一个人从(1, 1) ->(n, m),只能向下或者向右: 一个人从(n, 1) ->(1, m),只能向上或者向右.必须有一个相遇点, 相遇点的值不能被取到, 问两个人能得到的最大路径和是多少? dp[i][j]:表示从一个点出发的最大值:先预处理从(1,1) (1,m) (n,1) (n,m)四个点出发的4个dp最大值.然后枚举所有的点,但是这个点不能在边缘,考虑枚举点不够

Codeforces Round #168 (Div. 1) B. Zero Tree 树形dp

题目链接: http://codeforces.com/problemset/problem/274/B 题意: 给出一棵树,每个点有权值,每次操作可以对一个联通子集中的点全部加1,或者全部减1,且每次操作必须包含点1,问最少通过多少次操作可以让整棵树每个点的权值变为0. 思路: http://blog.csdn.net/qq_24451605/article/details/48622953 定义状态up[u],down[u]代表点u被加操作的次数和点u被减操作的次数 因为必须包含点1,所以我