https://nanti.jisuanke.com/t/30994
题意
给你n个题目,对于每个题目,在做这个题目之前,规定了必须先做哪几个题目,第t个做的题目i得分是t×ai+bi问最终的最大得分是多少?
分析
枚举所有状态,在转移时判断合法性,然后直接转移就好了。dp初始化为-inf,边界值dp[0]=0;
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <string> #include <algorithm> #include <cmath> #include <ctime> #include <vector> #include <queue> #include <map> #include <stack> #include <set> #include <bitset> #include <ctime> using namespace std; typedef long long ll; typedef unsigned long long ull; #define ms(a, b) memset(a, b, sizeof(a)) #define pb push_back #define mp make_pair #define pii pair<int, int> #define eps 0.0000000001 #define IOS ios::sync_with_stdio(0);cin.tie(0); #define random(a, b) rand()*rand()%(b-a+1)+a #define ne S, T, w, opi acos(-1) const ll INF = 0x3f3f3f3f3f3f3f3fll; const int inf = 0x3f3f3f3f; const int maxn = (1<<20) +10; const int maxm = 1e6 +10; const int mod = 100000007; int n, m, k; struct point{ int a,b,k; int f; }p[25]; ll dp[maxn]; int num[maxn]; int bit[maxn]; int main(){ #ifdef LOCAL freopen("input.txt", "r", stdin); // freopen("output.txt", "w", stdout); #endif int n,tmp; scanf("%d",&n); for(int i=0;i<=n;i++) bit[i]=1<<i; for(int i=0;i<(1<<n);i++){ num[i]=__builtin_popcount(i); } for(int i=0;i<n;i++) { scanf("%d%d%d",&p[i].a,&p[i].b,&p[i].k); p[i].f=0; for(int j=0;j<p[i].k;j++) { scanf("%d",&tmp); // p[i].f|=(1<<(tmp-1)); p[i].f|=bit[tmp-1]; } } ll ans=0; memset(dp,-inf,sizeof(dp)); dp[0]=0; for(int i=0;i<bit[n];i++){ if(dp[i]==-inf) continue; ans=max(ans,dp[i]); for(int j=0;j<n;j++){ if(i&bit[j]) continue; if((i&p[j].f)!=p[j].f) continue; dp[i|bit[j]]=max(dp[i|bit[j]],dp[i]+1ll*(num[i]+1)*p[j].a+p[j].b); } } // cout<<ans<<endl; printf("%lld\n",ans); return 0; }
原文地址:https://www.cnblogs.com/fht-litost/p/9591453.html
时间: 2024-10-09 08:16:35