codeforces 580D Kefa and Dishes (状压dp)

8 篇文章 0 订阅

题意:有n种菜(每一种菜有一个满意值ai>=0),你准备吃m种,每种一次。但是如果你按某种规则吃两种菜的话会增加额外的满意值,比如规则(xi yi ci)就是你先吃第xi个菜,然后马上吃第yi个菜,那么你就会额外增加ci点满意值。有k个这样的规则,问你吃m种菜后的最大满意值是多少。

dp[st][i] 代表在 st状态下,种第i棵菜 然后状态转移 如果在st状态下,已经种了j,那么可以选择把ij种一起,那么转移方程就是 种不中一起 dp[i][j]=max(dp[i][j],dp[st ^ (1<<i)+a[i]+com[i][j])

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int com[1010][1010];
ll dp[(1<<18)+10][20];
int a[10101];
int n;

int Cnt(int x)
{
	int cn=0;
	for(int i=0;i<n;i++)
	{
		if(x&(1<<i)) cn++;
	}
	return cn;
}
int main()
{
	int m,k;
	cin>>n>>m>>k;
	for(int i=0;i<n;i++)
		scanf("%d",&a[i]);
	for(int i=0;i<k;i++)
	{
		int x,y,c;
		scanf("%d%d%d",&x,&y,&c);
		x--,y--;
		com[x][y]=c;
	}
	int end=1<<n;
	ll ans=0;
	memset(dp,0,sizeof(dp));
	for(int st=0;st<end;st++)
	{
		for(int i=0;i<n;i++)
		{
			if(st&(1<<i))
			{
				dp[st][i]=a[i];
				for(int j=0;j<n;j++)
				{
					if(i!=j&&(st&(1<<j)))
					{

						dp[st][i]=max(dp[st][i],dp[st^(1<<i)][j]+a[i]+com[i][j]);
					}
				}
			}
		if(Cnt(st)==m)
		{
			ans=max(ans,dp[st][i]);
		}
	}
	}
	cout<<ans<<endl;
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值