题意:
n道题,每道题有ai和bi,完成这道题需要先完成若干道题,完成这道题可以得到分数t*ai+bi,其中t是时间
1s, n<=20
思路:
由n的范围状压,状态最多1e6
然后dfs,注意代码中dfs里的剪枝,
对一个状态statu,因为贪心的取最大值就行,所以及时剪枝
代码:
当时写不出来真是菜的活该
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<cstring> #include<string> #include<stack> #include<queue> #include<deque> #include<set> #include<vector> #include<map> #include<functional> #define fst first #define sc second #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) #define lson l,mid,root<<1 #define rson mid+1,r,root<<1|1 #define lc root<<1 #define rc root<<1|1 #define lowbit(x) ((x)&(-x)) using namespace std; typedef double db; typedef long double ldb; typedef long long ll; typedef unsigned long long ull; typedef pair<int,int> PI; typedef pair<ll,ll> PLL; const db eps = 1e-6; const int mod = 1e9+7; const int maxn = 2e6+100; const int maxm = 2e6+100; const int inf = 0x3f3f3f3f; const ll Inf = 0x3f3f3f3f3f3f3f3f; const db pi = acos(-1.0); int n; ll dp[maxn];//达到status的最大值 ll a[30], b[30]; int s[30]; vector<int>nd[30]; void init(){ for(int i = 1; i <= n; i++){ int ans = 0; int sz = nd[i].size(); for(int j = 0; j < sz; j++){ ans|=(1<<(nd[i][j]-1)); } s[i]=ans; } return; } void dfs(int cnt, int statu, ll ans){ dp[statu] = max(dp[statu], ans); if(cnt == n)return; for(int i = 1; i <= n; i++){ if(((1<<(i-1))&statu)!=0)continue; if((s[i]&statu)!=s[i])continue; dfs(cnt+1,statu|(1<<(i-1)), ans + (cnt+1)*a[i]+b[i]); } return; } int main(){ mem(dp,-1); scanf("%d", &n); for(int i = 1; i <= n; i++){ int num; scanf("%lld %lld %d", &a[i], &b[i], &num); for(int j = 0; j < num; j++){ int x; scanf("%d",&x); nd[i].pb(x); } } init(); dfs(0,0,0); printf("%lld",dp[(1<<n)-1]<0?0:dp[(1<<n)-1]); return 0; } /* */
原文地址:https://www.cnblogs.com/wrjlinkkkkkk/p/10182537.html
时间: 2024-11-09 01:13:02