P4877 [USACO14FEB] Cow Decathlon G
题解:P4877 [USACO14MAR] Sabotage G
题目大意
有 \(n\) 天,每天可以安排一个不同的奶牛挤奶。每头奶牛在第 \(i\) 天有特定的产量值,且在第 \(i\) 天结束时可能有多个奖励条件,求能获得的最大总产量。
题意分析
像这种没有思路的题目,先看一下 DP 可不可行,再观察到数据范围 \(n \le 20\),不难想到状压,于是:
设 \(f_{i,mask}\) 表示前 \(i\) 天,已经挤过奶的奶牛集合为 \(mask\) 时的最大产量,接着考虑怎么转移。
状态转移
-
安排奶牛:对于第 \(i\) 天,从所有未挤奶的奶牛中选择一头,更新状态:
\[f_{i,mask+2^j} = \max(f_{i,mask+2^j}, f_{i-1,mask}+wis_{j,i}) \]其中 \(wis_{j,i}\) 表示奶牛 \(j\) 在第 \(i\) 天的产量。
-
奖励结算:在第 \(i\) 天结束时,根据当前产量 \(f_{i,mask}\) 结算奖励。
奖励条件按所需产量降序排序,依次判断并累加奖励值。
时间复杂度
状态数:\(O(n \cdot 2^n)\)。转移复杂度:\(O(n)\),总复杂度:\(O(n \cdot 2^n)\),还有一点小常数。在 \(n \le 20\) 时可接受。
CODE
#include<bits/stdc++.h>
#define wk(x) write(x),putchar(' ')
#define wh(x) write(x),putchar('\n')
#define N 21
#define M 1100005
using namespace std;
int n,m,k,ans;
int wis[N][N],f[N][M];
struct Q{
int x,y;
bool operator<(const Q&A)const{
return A.x<x;
}
};
vector<Q> kis[N];
void read(int &x){
x=0;int ff=1;char ty;
ty=getchar();
while(!(ty>='0'&&ty<='9')){
if(ty=='-') ff=-1;
ty=getchar();
}
while(ty>='0'&&ty<='9')
x=(x<<3)+(x<<1)+ty-'0',ty=getchar();
x*=ff;return;
}
void write(int x){
if(x==0){
putchar('0');return;
}
if(x<0){
x=-x;putchar('-');
}
char asd[201];int ip=0;
while(x) asd[++ip]=x%10+'0',x/=10;
for(int i=ip;i>=1;i--) putchar(asd[i]);
return;
}
int Get(int x,int y=0){
while(x){
if(x&1) y++;
x>>=1;
}return y;
}
signed main(){
read(n),read(m);
for(int i=1,x,y,z;i<=m;i++){
read(x),read(y),read(z);
kis[x].push_back((Q){y,z});
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
read(wis[i][j]);
}
}
for(int i=1;i<=n;i++) sort(kis[i].begin(),kis[i].end());//按p排序肯定最优,这点需要注意!
for(int i=1;i<=n;i++){
for(int p=0;p<=(1<<n)-1;p++){
if(Get(p)!=i-1) continue;//避免无效状态
for(int j=1;j<=n;j++){
if((p|(1<<(j-1)))==p) continue;//重复
f[i][p|(1<<(j-1))]=max(f[i][p|(1<<(j-1))],f[i-1][p]+wis[j][i]);//转移
ans=max(f[i][p|(1<<(j-1))],ans);//取最大值
}
}
for(int p=0;p<=(1<<n)-1;p++){
if(Get(p)!=i) continue;//避免无效状态,同上
for(int j=0;j<(int)kis[i].size();j++){
if(f[i][p]>=kis[i][j].x) f[i][p]+=kis[i][j].y,ans=max(f[i][p],ans);//计算奖励分
}
}
}
wh(ans);
return 0;
}
本文来自博客园,作者:Red_river_hzh,转载请注明原文链接:https://www.cnblogs.com/Red-river-hzh/p/19926910

浙公网安备 33010602011771号