还是比较明显的模型,明显是把k,p小的先做了,然后设f[i]表示状态为i的最大分值。
转移显然。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const int N=1<<21;
int f[N];
struct node
{
int k,p,a;
}a[30];
int s[25][25],n,m;
bool cmp(node a,node b)
{
if (a.k!=b.k)return a.k<b.k;
if (a.p!=b.p)return a.p<b.p;
return a.a<b.a;
}
int main()
{
scanf("%d%d",&n,&m);
fo(i,1,m)
{
scanf("%d%d%d",&a[i].k,&a[i].p,&a[i].a);
}
sort(a+1,a+1+m,cmp);
fo(i,1,n)
fo(j,1,n)scanf("%d",&s[i][j]);
int mx=(1<<n)-1;
fo(i,0,mx-1)
{
int num=1,t=0;
fo(j,1,n)if (i&(1<<j-1))num++;
fo(j,1,m)if (a[j].k==num)
{
t=j;
break;
}
int k=t;
fo(j,1,n)
if (!(i&(1<<j-1)))
{
int sum=0;
t=k;
while (t!=0&&t<=m&&a[t].k==num&&f[i]+s[j][num]+sum>=a[t].p)
{
sum+=a[t].a;
t++;
}
f[i|(1<<j-1)]=max(f[i|(1<<j-1)],f[i]+sum+s[j][num]);
}
}
printf("%d\n",f[mx]);
}