[动态规划] hdu 3602-2012 和 USACO Section 3.4 Rockers
2011-07-17 10:59
507 查看
周五我们做的杭电OJ上virtual contest,其中有一道《2012》,在problem中的题号为3602。比赛的时候我dp了一下,结果wrong了。发现这个题的题意和我之前做的USACO上Section 3.4 - Rockers 很像,Rockers的题意是从N首歌曲中选出最多数量的歌曲放到M张光盘上,每个光盘只能放T分钟的歌曲,每首歌曲只能在一张盘上,还有个要求就是选出的歌曲放到盘上的顺序必须和原歌曲的顺序相同。由于数据范围很小,规划思想是:用dp[i][j][k]表示前i首歌曲用j张盘,且最后一张盘用了k分钟,代码如下:
/*
ID: morgan_xww
LANG: C
TASK: rockers
*/
#include <stdio.h>
int Max(int a, int b)
{
return (a > b ? a : b);
}
int main()
{
freopen("rockers.in", "r", stdin);
freopen("rockers.out", "w", stdout);
int N, M, T, i, j, k;
int a[21];
int dp[21][21][21]={0};
scanf("%d %d %d", &N, &T, &M);
for (i=1; i<=N; i++)
scanf("%d", &a[i]);
for (i=1; i<=N; i++)
for (j=1; j<=M; j++)
for (k=1; k<=T; k++)
{
//不放第i首歌曲;不用第j个盘
dp[i][j][k] = Max(dp[i-1][j][k], dp[i][j-1][T]);
if (a[i] < k)
//把歌曲i插到第j个盘后面
dp[i][j][k] = Max(dp[i][j][k], dp[i-1][j][k-a[i]]+1);
else if (a[i] == k)
//把歌曲i插到一张新盘上
dp[i][j][k] = Max(dp[i][j][k], dp[i-1][j-1][T]+1);
}
printf("%d\n", dp
[M][T]);
exit(0);
}
杭电的这个题意是:N个国家,M个飞船,每个国家有人数num,如果上飞船就给联合国value钱,选出某些国家上船,使联合国赚得的钱最多,而且被选出的国家上船的顺序必须和原给的国家顺序一致。代码如下:
/*
ID: morgan_xww
LANG: C
TASK: rockers
*/
#include <stdio.h>
int Max(int a, int b)
{
return (a > b ? a : b);
}
int main()
{
freopen("rockers.in", "r", stdin);
freopen("rockers.out", "w", stdout);
int N, M, T, i, j, k;
int a[21];
int dp[21][21][21]={0};
scanf("%d %d %d", &N, &T, &M);
for (i=1; i<=N; i++)
scanf("%d", &a[i]);
for (i=1; i<=N; i++)
for (j=1; j<=M; j++)
for (k=1; k<=T; k++)
{
//不放第i首歌曲;不用第j个盘
dp[i][j][k] = Max(dp[i-1][j][k], dp[i][j-1][T]);
if (a[i] < k)
//把歌曲i插到第j个盘后面
dp[i][j][k] = Max(dp[i][j][k], dp[i-1][j][k-a[i]]+1);
else if (a[i] == k)
//把歌曲i插到一张新盘上
dp[i][j][k] = Max(dp[i][j][k], dp[i-1][j-1][T]+1);
}
printf("%d\n", dp
[M][T]);
exit(0);
}
杭电的这个题意是:N个国家,M个飞船,每个国家有人数num,如果上飞船就给联合国value钱,选出某些国家上船,使联合国赚得的钱最多,而且被选出的国家上船的顺序必须和原给的国家顺序一致。代码如下:
/** dp[i][j].nship 和 dp[i][j].left 分别表示 从前i个总统赚到j元钱所需要的ship数量和最后一个ship的剩余空间。 dp[i][j]的状态从dp[i-1][j] 和的 dp[i-1][j-v[i]] 转化而来。 **/ #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; int n, m, k; int maxVal; struct CTY { int num; int value; } cty[101]; struct DP { int nship; //所需的飞船数量 int left; //最后一个飞船的剩余空间 bool tag; //标记该状态是否有效 void setValue(int a, int b, bool c) { nship = a; left = b; tag = c; } void add(DP d, CTY c) { if (d.tag == false) return ; if (d.left >= c.num) d.left -= c.num; else if (c.num <= k) { d.nship++; d.left = k-c.num; } else return ; if (d.nship > m) return ; if ( !tag || nship > d.nship || (nship == d.nship && left < d.left) ) setValue(d.nship, d.left, d.tag); } } dp[101][10001]; void solve() { memset(dp, 0, sizeof(dp)); for (int i=0; i<=n; i++) { dp[i][0].setValue(0, 0, true); } for (int i=1; i<=n; i++) { for (int j=1; j<=maxVal; j++) { if (dp[i-1][j].tag) dp[i][j] = dp[i-1][j]; if (j-cty[i].value >=0) dp[i][j].add(dp[i-1][j-cty[i].value], cty[i]); } } for (int j=maxVal; j>=0; j--) { if (dp [j].tag) { printf("%d\n", j); return ; } } } int main() { int nc; scanf("%d", &nc); while (nc--) { maxVal = 0; scanf("%d %d %d", &n, &m, &k); for (int i=1; i<=n; i++) { scanf("%d %d", &cty[i].num, &cty[i].value); cty[i].num++; maxVal += cty[i].value; } solve(); } return 0; }
相关文章推荐
- USACO-Section3.4 Raucous Rockers【动态规划】
- usaco 3.4 rockers 动态规划
- USACO-Section3.4 Electric Fences【数学】
- USACO-Section 3.4 American Heritage (分治)
- hdu 3602 2012
- USACO-Section 3.4 Electric Fence (模拟)
- USACO-Section 3.4 Raucous Rockers (DP)
- [DP]USACO Section 3.4 Raucous Rockers
- HDU 3602 2012【01 背包变形】
- USACO-Section1.5 Number Triangles [动态规划]
- USACO 3.4 Rockers
- USACO-Section1.6 Number Triangles (动态规划)
- USACO-Section2.2 Subset Sums【动态规划】
- USACO-Section2.2 Subset Sums [动态规划]
- USACO-Section2.3 Money Systems【动态规划】
- USACO-Section3.3 A Game【动态规划】
- HDU 3602 2012(2010 ACM-ICPC Multi-University Training Contest(16)——Host by NUDT)
- USACO-Section2.3 Longest Prefix【动态规划】
- USACO-Section2.3 Cow Pedigrees【动态规划】
- USACO Section 3.4 Raucous Rockers(状态压缩或DFS)