【jzoj2210】【DP】采访(interview)

57 篇文章 0 订阅
题目描述

你是一名记者,现在要求你去采访n 个国家的领导人。采访每一个国家的领导人需要消耗你的时间为t[i],但你可以收获价值为v[i]的信息,然后就能写成报道……
然而尴尬的是,有一些国家之间的关系属于敌对关系,因此如果一个国家的领导人知道你采访了他的敌对国家领导人,那么他就会拒绝你的采访。总之,你采访的国家中,任意选出一对国家都不能构成敌对关系,你才能够完成你的采访,否则某些部分就要落空。
你的Boss他给了你一个时间限制T,如果你在时间限制内没有完成采访任务,你就会被炒鱿鱼。当然,他希望你在时间限制T 内完成的采访累计起来的价值总和最大。

输入
第一行有三个数,第一个数为时间限制T,第二个数为国家数量n,第三个数为国家之间的敌对组数m。
接下来n 行,每行两个数,第一个数为t[i],第二个数为v[i]。
接下来m 行,每行有m[i]+1 个数,首先输入m[i],表示这一组中一共有多少国家是敌对关系,之后输入m[i]个数,表示这m[i]个国家两两之间为敌对关系(一组敌对关系的国家中,每两个国家都构成敌对关系,比如这一组是1,3,4,那么1 和3,1 和4,3 和4 都构成敌对关系),若m[i] = 1,那么这个国家与其他国家都不构成敌对关系。

输出
一个整数,表示最大价值V。

样例输入

10 5 2
5 10
7 9
6 3
1 13
8 1
3 1 3 4
2 2 5

样例输出

22

数据范围限制
60%的数据:m=1;
100%的数据:0≤T≤50000,0≤n≤500,1≤m≤10,n=∑m[i],即m[1]+m[2]+…=n,且敌对关系中每个国家编号只会出现一次。


解题思路

类似背包
f [ i ] [ k ] f[i][k] f[i][k]表示第 i i i圈敌对关系时间花费为 k k k得到最大的价值

( e n e m y [ ] [ ] enemy[][] enemy[][]存储敌对关系, j j j用来枚举关系圈里的国家)
f [ i ] [ k ] = m a x f[i][k]=max f[i][k]=max{ f [ i − 1 ] [ k − w [ e n e m y [ i ] [ j ] ] ] + v [ e n e m y [ i ] [ j ] ] f[i-1][k-w[enemy[i][j]]]+v[enemy[i][j]] f[i1][kw[enemy[i][j]]]+v[enemy[i][j]]}
( 1 < = i < = m , 1 < = j < = e n e m y [ i ] [ 0 ] , w [ e n e m y [ i ] [ j ] ] < = k < = t i m e ) (1<=i<=m,1<=j<=enemy[i][0],w[enemy[i][j]]<=k<=time) (1<=i<=m,1<=j<=enemy[i][0],w[enemy[i][j]]<=k<=time)

最后输出 f [ m ] [ t i m e ] f[m][time] f[m][time]

:不要尝试一维,一维行不通,因为这题比较bt


#include<iostream>
#include<cstdio>
using namespace std;
int ti,n,m,w[600],v[600],enemy[20][600],f[600][50100];
int main(){
	freopen("interview.in","r",stdin);
	freopen("interview.out","w",stdout);
	scanf("%d%d%d",&ti,&n,&m);
	for(int i=1;i<=n;i++)
	    scanf("%d%d",&w[i],&v[i]);
	for(int i=1;i<=m;i++){
		scanf("%d",&enemy[i][0]);
		for(int j=1;j<=enemy[i][0];j++)
		    scanf("%d",&enemy[i][j]);
	}
	for(int i=1;i<=m;i++){
		for(int j=1;j<=ti;j++)
		    f[i][j]=f[i-1][j];
		for(int j=1;j<=enemy[i][0];j++)
		    for(int k=ti;k>=w[enemy[i][j]];k--)
		        f[i][k]=max(f[i][k],f[i-1][k-w[enemy[i][j]]]+v[enemy[i][j]]);
	}
	printf("%d",f[m][ti]);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值