递推DP URAL 1167 Bicolored Horses

题目传送门

 1 /*
 2     题意:k个马棚,n条马,黑马1, 白马0,每个马棚unhappy指数:黑马数*白马数,问最小的unhappy指数是多少
 3     状态转移方程:dp[i][l] = min (dp[i][l], dp[i-1][j] + cur * (l - j - cur)) 表示第l匹马要不还在i马棚,或者去新的马棚
 4     本题关键在dp初始化INF,由于黑马白马的表示简单,求指数方便
 5 */
 6 #include <cstdio>
 7 #include <iostream>
 8 #include <algorithm>
 9 #include <cstring>
10 #include <cmath>
11 using namespace std;
12
13 const int MAXN = 5e2 + 10;
14 const int INF = 0x3f3f3f3f;
15 int dp[MAXN][MAXN];
16 int a[MAXN], sum[MAXN];
17
18 int main(void)        //URAL 1167 Bicolored Horses
19 {
20     //freopen ("L.in", "r", stdin);
21
22     int n, k;
23     while (scanf ("%d%d", &n, &k) == 2)
24     {
25         memset (sum, 0, sizeof (sum));
26         for (int i=0; i<=k; ++i)
27             for (int j=0; j<=n; ++j)    dp[i][j] = INF;
28         for (int i=1; i<=n; ++i)    {scanf ("%d", &a[i]);    sum[i] = a[i];    sum[i] += sum[i-1];}
29
30         dp[0][0] = 0;
31         for (int i=1; i<=k; ++i)
32         {
33             for (int j=0; j<=n; ++j)
34             {
35                 for (int l=j+1; l<=n; ++l)
36                 {
37                     int cur = sum[l] - sum[j];
38                     dp[i][l] = min (dp[i][l], dp[i-1][j] + cur * (l - j - cur));
39                 }
40             }
41         }
42
43         printf ("%d\n", dp[k][n]);
44     }
45
46     return 0;
47 }
时间: 2024-10-09 17:54:09

递推DP URAL 1167 Bicolored Horses的相关文章

URAL 1167. Bicolored Horses (DP)

题目链接 题意 :农夫每天都会放马出去,然后晚上把马赶入马厩,于是让马排成一行入马厩,但是不想马走更多的路,所以让前p1匹入第一个马厩,p2匹马入第二个马厩…………但是他不想让他的任何一个马厩空着,所有的马都必须入马厩.有两种颜色的马,如果 i 匹黑马与 j 匹白马同在一个马厩,不愉快系数是 i * j,总系数就是k个系数相加.让总系数最小. 思路 : dp[i][j] 代表的是前 i 个马厩放 j 匹马的最小不愉快系数值. 1 //1167 2 #include <cstdio> 3 #in

递推DP URAL 1353 Milliard Vasya&#39;s Function

题目传送门 1 /* 2 题意:1~1e9的数字里,各个位数数字相加和为s的个数 3 递推DP:dp[i][j] 表示i位数字,当前数字和为j的个数 4 状态转移方程:dp[i][j] += dp[i-1][j-k],为了不出现负数 5 改为:dp[i][j+k] += dp[i-1][j] 6 */ 7 #include <cstdio> 8 #include <cstring> 9 #include <cmath> 10 #include <algorithm

递推DP URAL 1031 Railway Tickets

题目传送门 1 /* 2 简单递推DP:读题烦!在区间内的都更新一遍,dp[]初始化INF 3 注意:s1与s2大小不一定,坑! 4 详细解释:http://blog.csdn.net/kk303/article/details/6847948 5 */ 6 #include <cstdio> 7 #include <iostream> 8 #include <algorithm> 9 #include <cstring> 10 #include <s

递推DP URAL 1119 Metro

题目传送门 1 /* 2 题意:已知起点(1,1),终点(n,m):从一个点水平或垂直走到相邻的点距离+1,还有k个抄近道的对角线+sqrt (2.0): 3 递推DP:仿照JayYe,处理的很巧妙,学习:) 4 好像还要滚动数组,不会,以后再补 5 */ 6 #include <cstdio> 7 #include <iostream> 8 #include <algorithm> 9 #include <cmath> 10 #include <cs

递推DP URAL 1260 Nudnik Photographer

题目传送门 1 /* 2 递推DP: dp[i] 表示放i的方案数,最后累加前n-2的数字的方案数 3 */ 4 #include <cstdio> 5 #include <algorithm> 6 #include <cmath> 7 #include <cstring> 8 using namespace std; 9 10 const int MAXN = 1e4 + 10; 11 const int INF = 0x3f3f3f3f; 12 int

递推DP URAL 1017 Staircases

题目传送门 1 /* 2 题意:给n块砖头,问能组成多少个楼梯,楼梯至少两层,且每层至少一块砖头,层与层之间数目不能相等! 3 递推DP:dp[i][j] 表示总共i块砖头,最后一列的砖头数是j块的方案数 4 状态转移方程:dp[i][j] += dp[i-j][k] 表示最后一列是j,那么上一个状态是少了最后一列 5 总共i-j块砖头,倒数第二列是k块砖头.k<j, j<=i 6 最后累加dp[n][i], i<n因为最少要两层 7 dp[0][0] = 1; 8 还有更简单的做法,没

Ural 1167 Bicolored Horses (DP)

题目地址:Ural 1167 感觉这题的思路类似于背包的做法.. 先预处理出来每个马与之前所有的马的0的数量和1的数量,用数组a[0][i]和a[1][i]来表示. 然后再用数组dp[i][j]来表示当前第i个马槽最右端为第j个马时的最小值. dp的时候先枚举马槽,再用n*n枚举当前的马槽要选用的马的区间.这样总时间复杂度是O(n*n*k). 代码如下: #include <iostream> #include <cstdio> #include <string> #i

递推DP URAL 1081 Binary Lexicographic Sequence

题目传送门 1 /* 2 dp[i][1]/dp[i][0] 表示从左往右前i个,当前第i个放1或0的方案数 3 k -= dp[n][0] 表示当前放0的方案数不够了,所以必须放1,那么dp[n][0]个方案数都不能用了 4 相当于k减去这么多 5 详细解释:http://www.cnblogs.com/scau20110726/archive/2013/02/05/2892587.html 6 */ 7 #include <cstdio> 8 #include <algorithm&

递推DP URAL 1586 Threeprime Numbers

题目传送门 1 /* 2 题意:n位数字,任意连续的三位数字组成的数字是素数,这样的n位数有多少个 3 最优子结构:考虑3位数的数字,可以枚举出来,第4位是和第3位,第2位组成的数字判断是否是素数 4 所以,dp[i][j][k] 表示i位数字,最高位数字j,第二高位数字k 5 状态转移方程:dp[i][j][k] += dp[i-1][k][l] 6 注意:最高位从1开始枚举:) 7 详细解释:http://blog.csdn.net/zhangyanxing666/article/detai