hdu 3535 AreYouBusy(分组背包的变形---各种分组背包)
来源:互联网 发布:php网络验证系统源码 编辑:程序博客网 时间:2024/05/22 01:53
题目分析:0代表每组内的job至少取一件;1代表最多取一件;2代表可以自由取,就相当于对这一组内的job实行01背包......
注意: 1. One job can be done only once.开始没注意到这句话,还以为每组内的每个job可以做多次....囧,,,
2.这个题花了我一天多的时间,最后看别人的解题报告才过的,,,,
3.应该先做 hdu 3033的,这个相对于这个简单一些
4.这个貌似不能压缩空间.....我开始压缩空间做的,一直错,样例都过不了
/*该题要用分组背包做,这里就是要怎样处理0必须选,1最多选一个,2任意选的问题;这里我们就开个二维数组;f[i][j],i表示第组,j表示时间;当该组为0时,我们在该组的选择可以来自上一组的结果,也可以来自该组的结果;如果为1那么结果只能依赖上一组的结果,如果依赖本组那么就会造成该组会多选;为2是那就是一个01背包;*/#include<iostream>#include<cstdio>#include<algorithm>#include<memory.h>using namespace std;struct node{ int c,g;}arr[1000];int dp[1000][1000];int main(){int n,t,m,s;while(scanf("%d %d",&n,&t)!=EOF){memset(dp,-1,sizeof(dp));memset(dp[0],0,sizeof(dp[0]));for(int x=1;x<=n;x++){ scanf("%d %d",&m,&s); // memset(dp,0,sizeof(dp));****不要再犯这样的低级错误 for(int i=1;i<=m;i++)scanf("%d %d",&arr[i].c,&arr[i].g); if(s==0)//每组内.至少取一件,我们在该组的选择可以来自上一组的结果.也可以来自该组的结果;{ for(int i=1;i<=m;i++) // for(int i=0;i<=t;i++) for(int k=t;k>=arr[i].c;k--) // for(int k=1;k<=m;k++) { if(dp[x][k-arr[i].c]!=-1) dp[x][k]=max(dp[x][k],dp[x][k-arr[i].c]+arr[i].g);//如果dp[i][k-arr[i].c]存在,则表示i组已经取过了,就相当与在去过的基础上再取,即,至少一个 if(dp[x-1][k-arr[i].c]!=-1) dp[x][k]=max(dp[x][k],dp[x-1][k-arr[i].c]+arr[i].g);//确保取一个 }}else if(s==1)//每组至多取一件,就是分组背包的原形.{//只能依赖上一组的结果,如果依赖本组那么就会造成该组会多选 for(int k=1;k<=m;k++)//for(int i=t;i>=0;i--) for(int i=t;i>=0;i--)//for(int k=1;k<=m;k++) { dp[x][i]=max(dp[x][i],dp[x-1][i]); if(i>=arr[k].c && dp[x-1][i-arr[k].c]!=-1) dp[x][i]=max(dp[x][i],dp[x-1][i-arr[k].c]+arr[k].g); }}else//每组内的,可以取任意件,相对于对每一组内的每一件,进行01背包{for(int k=0;k<=t;k++)dp[x][k]=dp[x-1][k]; for(int k=1;k<=m;k++) for(int i=t;i>=arr[k].c;i--) if(dp[x][i-arr[k].c]!=-1) dp[x][i]=max(dp[x][i],dp[x][i-arr[k].c]+arr[k].g);} }/*if(dp[n][t]==0)printf("-1\n");else*/ printf("%d\n",dp[n][t]);}system("pause");return 0;}/***************************//有错,压缩空间#include<iostream>#include<cstdio>#include<algorithm>#include<memory.h>using namespace std;struct node{ int c,g;}arr[1000];int dp[1000000];int main(){int n,t,m,s;while(scanf("%d %d",&n,&t)!=EOF){memset(dp,0,sizeof(dp));for(int x=1;x<=n;x++){ scanf("%d %d",&m,&s); // memset(dp,0,sizeof(dp));****不要再犯这样的低级错误 for(int i=1;i<=m;i++)scanf("%d %d",&arr[i].c,&arr[i].g); if(s==0)//每组内.至少取一件,我们在该组的选择可以来自上一组的结果.也可以来自该组的结果;{ for(int i=1;i<=m;i++) // for(int i=0;i<=t;i++) for(int k=t;k>=arr[i].c;k--) // for(int k=1;k<=m;k++) dp[k]=max(dp[k],dp[k-arr[i].c]+arr[i].g);}else if(s==1)//每组至多去一件,就是分组背包的原形.{//只能依赖上一组的结果,如果依赖本组那么就会造成该组会多选 for(int i=t;i>=0;i--) for(int k=1;k<=m;k++) if(i-arr[k].c>=0) dp[i]=max(dp[i],dp[i-arr[k].c]+arr[k].g);}else//每组内的,可以取任意件,相对于对每一组内的每一件,进行01背包{ for(int k=1;k<=m;k++) for(int i=t;i>=arr[k].c;i--) dp[i]=max(dp[i],dp[i-arr[k].c]+arr[k].g);} }if(dp[t]==0)printf("-1\n");else printf("%d\n",dp[t]);}system("pause");return 0;}*//***************比人的代码个细节不懂,谁知道的话帮个忙,留个言~三种背包,每组至少、至多取一个或随意取多少注释在代码中?#include<cstdio>#include<cstring>int dp[110][110];int max(int a,int b){ return a>b?a:b;}int main(){ int n,T,i,j,k,m,s,w,v; while(scanf("%d%d",&n,&T)!=EOF) { memset(dp,0,sizeof(dp)); for(i=1;i<=n;i++) { scanf("%d%d",&m,&s); if(s==0)//至少选一个 { for(j=0;j<=T;j++) dp[i][j]=-1;//保证下面会有一个被选中 for(j=1;j<=m;j++) { scanf("%d%d",&w,&v); for(k=T;k>=w;k--) { //下面这两句话为什么一换就错啊,不懂了。。。。 if(dp[i][k-w]!=-1) dp[i][k]=max(dp[i][k],dp[i][k-w]+v);//如果dp[i][k-w]存在,则表示i组已经取过了,就相当与在去过的基础上再取,即,至少一个 if(dp[i-1][k-w]!=-1) dp[i][k]=max(dp[i-1][k-w]+v,dp[i][k]);//保证一定取一个 } } } if(s==1)//至多选一个 { for(j=0;j<=T;j++) dp[i][j]=dp[i-1][j]; for(j=1;j<=m;j++) { scanf("%d%d",&w,&v); for(k=T;k>=w;k--) { if(dp[i-1][k-w]!=-1) dp[i][k]=max(dp[i][k],dp[i-1][k-w]+v); } } } if(s==2)//随意选 { for(j=0;j<=T;j++) dp[i][j]=dp[i-1][j]; for(j=1;j<=m;j++) { scanf("%d%d",&w,&v); for(k=T;k>=w;k--) { if(dp[i][k-w]!=-1) dp[i][k]=max(dp[i][k],dp[i][k-w]+v); } } } } int ans=-1; for(i=0;i<=T;i++) { if(dp[n][i]>ans) ans=dp[n][i]; } printf("%d\n",ans); } return 0;} View Code 分类: 动态规划标签: 背包绿色通道:好文要顶关注我收藏该文与我联系 Because Of You关注 - 1粉丝 - 5+加关注0 0(请您对文章做出评价)« 博主前一篇:关于分组背包» 博主后一篇:zstu 1032 拆分物品 再01背包posted @ 2011-11-19 15:00 Because Of You Views(48) Comments(0) Edit 收藏*//*该题要用分组背包做,这里就是要怎样处理0必须选,1最多选一个,2任意选的问题;这里我们就开个二维数组;f[i][j],i表示第组,j表示时间;当该组为0时,我们在该组的选择可以来自上一组的结果,也可以来自该组的结果;如果为1那么结果只能依赖上一组的结果,如果依赖本组那么就会造成该组会多选;为2是那就是一个01背包;*//*http://www.haogongju.net/art/1343345#include<cstdio>#include<iostream>#include<cstring>using namespace std;class node{ public: int cost,happy;};class Node{ public: node t[124]; int type,N; };Node T[124];int Max( int a, int b ){ return a > b ? a : b; }int DP( int n , int time ){ int f[124][124]; memset( f , -1 , sizeof( f ) ); memset( f[0] , 0 ,sizeof(f[0]) ); for( int i = 1 ; i <= n ; i ++ ) { switch( T[i].type ) { case 0: //至少取一件,即依赖上组,一依赖本组 for( int j = 0 ; j < T[i].N; j++ ) for( int k = time ; k >= T[i].t[j].cost ; k-- ) { if( f[i][k-T[i].t[j].cost]!=-1 ) f[i][k] = Max(f[i][k],f[i][k-T[i].t[j].cost] + T[i].t[j].happy); if( f[i-1][k-T[i].t[j].cost]!=-1 ) f[i][k] = Max(f[i][k],f[i-1][k-T[i].t[j].cost] + T[i].t[j].happy); } break; case 1://至多取一件,只依赖本组 for( int j = 0 ; j < T[i].N; j++ ) for( int k = time ; k >= 0 ; k-- ) { f[i][k] = Max(f[i-1][k],f[i][k]); //???? if( k-T[i].t[j].cost>=0&&f[i-1][k-T[i].t[j].cost] != -1 ) f[i][k] = Max( f[i][k],f[i-1][k-T[i].t[j].cost] + T[i].t[j].happy ); } break; case 2://任意取,01背包 for( int j = 0 ; j <= time ; j++) { f[i][j] = f[i-1][j]; } for( int j = 0 ; j < T[i].N; j++ ) for( int k = time ; k >0; k-- ) { if( k-T[i].t[j].cost>=0&&f[i][k-T[i].t[j].cost]!=-1 ) f[i][k] = Max(f[i][k], f[i][k-T[i].t[j].cost] + T[i].t[j].happy); } break; } //switch } return f[n][time];}int main( ){int n , m , time, type;while( scanf( "%d%d",&n , &time )==2 ){for( int i = 1 ; i <= n ; i++ ){scanf( "%d%d",&T[i].N, &T[i].type );for( int j = 0 ; j < T[i].N ; j++ ){scanf( "%d%d",&T[i].t[j].cost , &T[i].t[j].happy );}}printf("%d\n", DP( n , time )); }return 0; }*/
- hdu 3535 AreYouBusy(分组背包的变形---各种分组背包)
- hdu 3535 AreYouBusy(各种分组背包)
- hdu 3535 AreYouBusy[各种分组背包]
- hdu 3535 AreYouBusy(混合分组背包)
- hdu 3535 AreYouBusy(经典分组背包)
- HDU 3535:AreYouBusy(分组背包)
- HDU 3535 AreYouBusy(分组背包)
- HDU 3535 AreYouBusy(混合背包与分组背包)
- hdu 3535 AreYouBusy(分组背包)(推荐)
- HDU 3535 AreYouBusy(混合背包+分组背包/至少取一件)
- hdu3535---AreYouBusy(混合分组背包,有坑点)
- HDOJ 3535 AreYouBusy (分情况的分组背包)
- HDU3535 AreYouBusy 混合分组背包
- 【分组背包】HDU 3535
- hdu 3535 分组背包
- hdu3033 分组背包变形
- hdu3033(分组背包变形)
- HDU 4341 Gold miner 分组背包变形
- iOS开发之多媒体播放
- 关于对dw cs3和dw cs4的一些看法!
- screen命令
- window命令行设置IP地址
- 深入分析MFC文档视图结构(项目实践)
- hdu 3535 AreYouBusy(分组背包的变形---各种分组背包)
- iOS开发之Objective-C与JavaScript的交互
- 【LGame入门学堂002.第一章】HelloWorld之搭建环境
- iOS开发之在地图上绘制出你运动的轨迹
- 计一个移动应用的本地缓存机制
- linux下出现段错误怎么排错
- 修改mysql的默认存储引擎
- 【LGame入门学堂003.第三章】 HelloWorld之绘制文本
- Asp.Net日期时间格式设置