您的位置:首页 > 其它

hdu4381Grid【微复杂的背包】

2015-11-09 18:37 411 查看
 拖了好久的题==从上周三没想完 到周四没状态 再到周末没学习==算是刷了将近一个月Dp专题的结尾吧 好难好难T^T

题意:一列有n个格子 m次操作可以将某段区间中x个格子涂成白的 问最后能有最多多少个白的==

真心没想到怎么能跟背包有关系@。@ 由于状态不好 ,看了好久题解才明白 由于题意中的区间一定是从两个端点开始的 ,那么利用这个性质,可以假定X的涂色的都是端点开始而且不间断的,多么多么像背包!那么怎么写呢?

首先,既然已经确定了是不间断的涂色,那么下标就可以直接反映出来有多少涂色的,dp数组反映出的就是需要操作次数~~对于第一问的涂色个数 就是两个数组的下标和了呗。第二问:Dp值和求最小值就好了嘛

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <vector>
#include <cmath>

using namespace std;
const int maxn = 2005;
struct node{
int aa,cor;
node(){}
node(int _aa,int _cor){
aa = _aa;   cor = _cor;
}
}x1[maxn],x2[maxn];
int n,m;
int dp1[maxn],dp2[maxn];
int sumx1,sumx2;

bool cmp(const node &p,const node &q){
return p.aa < q.aa;
}

int min(int a,int b)
{
return a<b?a:b;
}

int main()
{
int cas,ta=1;
scanf("%d",&cas);
while(cas--){
int i,j;
scanf("%d%d",&n,&m);

sumx1 = sumx2 = 1;
for(i=0; i<m; i++){
int key,yy,z;
scanf("%d%d%d",&key,&yy,&z);
if(key == 1){
x1[sumx1++] = node(yy,z);
}else{
x2[sumx2++] = node(n+1-yy,z);
}
}
sort(x1+1,x1+sumx1,cmp);
sort(x2+1,x2+sumx2,cmp);
memset(dp1,0x3f,sizeof(dp1));
memset(dp2,0x3f,sizeof(dp2));

dp1[0] = dp2[0] = 0;
for(i=1; i<sumx1; i++){
for(j=x1[i].aa; j>=x1[i].cor; j--){
dp1[j] = min(dp1[j],dp1[j-x1[i].cor]+1);
}
}

for(i=1; i<sumx2; i++){
for(j=x2[i].aa; j>=x2[i].cor; j--){
dp2[j] = min(dp2[j],dp2[j-x2[i].cor]+1);
}
}

int ans = 0,anssum = 0,tmp;
for(i=1; i<=n; i++){
for(j=0; j<=i; j++){
tmp = dp1[j] + dp2[i-j];
if(tmp <= m){
if(ans != i){
ans = i;   anssum = tmp;
}else if(tmp < anssum){
anssum = tmp;
}
}
}
}

printf("Case %d: %d %d\n",ta++,ans,anssum);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: