教練my手下有 n 名隊員,現在他要挑選 5 人組成乙個籃球隊來參賽。眾所周知,乙個籃球隊伍有五個不同的位置(控球後衛,得分後衛,小前鋒,大前鋒,中鋒),現在教練my給出每名隊員在每個位置的能力。
注:如果乙個隊員作為控球後衛出戰,則他只能發揮他的控球後衛的能力值。(其他位置類似)
教練my想讓你幫忙選擇出 5 名隊員,分別放置在隊伍中的不同位置。求他們組成的隊伍的最大能力值之和
狀壓dp,揹包寫法:
解析:
#include#define ll long long
#define maxn 100005
using namespace std;
ll val[maxn][6];
ll dp[maxn][35]=;//前i個人,在j狀態下的最大權值和
int main()}}
}printf("%lld\n",dp[n][31]);
return 0;
}
方法2:貪心+廣搜
選出每種能力的前 5 個人(很顯然,如果乙個人某個位置不在前 5,
那麼他不可能作為此位置出戰),總共選出 25 人(可能重複)
然後使用 dfs 判斷答案即可(當然,這一步可以用狀壓 dp 優化時間,但沒必要)
ac:
#include#define ll long long
#define maxn 100005
using namespace std;
struct node
}a[10][maxn];
ll vis[maxn]=;
ll maxs=0;
void dfs(ll x,ll sum)
for(ll i=1;i<=5;i++)
}}int main()
費用流:
源點->(n+1,n+2,n+3,n+4,n+5)-> [val[i][j]](1~n)->t
源點5條路出發,每條僅有1條流量為1的邊
這五個點代表5個位置,每個位置連n個人,流量為1,費用為val[i][j]
n個**向終點,流量為1,1個人僅僅只能在乙個位置上
#include#include#include#include#define ll long long
#define maxn 1000005
#define maxm 1000005
using namespace std;
//dis最小花費;pre每個點的前驅;last每個點的所連的前一條邊;flow源點到此處的流量
bool vis[maxn];
ll dis[maxn],pre[maxn],last[maxn],flow[maxn];
ll maxflow,mincost;
ll to[maxm<<1],nxt[maxm<<1],water[maxm<<1],val[maxm<<1],head[maxm<<1];
ll tot,gk;
queue que;
void init()
void addedge(ll u,ll v,ll f,ll w)
void add(ll u,ll v,ll f,ll w)
bool spfa(ll s,ll t)}}
}return pre[t]!=-1;
}void mcmf(ll s,ll t)
}}int main()
add(i,t,1,0);
}mcmf(s,t);
printf("%lld",-mincost);
return 0;
}
玉公尺田 狀壓DP 記搜
乙個n m role presentation n m n m的矩陣裡,有幾個是可以種植玉公尺的。求玉公尺種植不相連的方案數。dfs爆搜 只 能拿90分,正解是狀壓dp。可以把可種植玉公尺的土地用1表示,貧瘠的土地用0表示,每一行串成的數字就是乙個二進位制數,狀態壓縮後,就成了乙個較小的十進位制數。...
hdu 檢測賽 Problem C(狀壓dp)
新年伊始,集訓隊迎來了15級新生。教練打算將大家n 2 n 20 個人分成ab兩隊,已知每兩個新生之間都有相互的思念值,如果分到一隊的話經常見面不會思念,但是如果不被分到一隊的話,他們就會無比思念對方,此時兩個人之間的思念值為f 0 f 10000 教練想知道,分隊使大家的思念值總和 即a隊的每個人...
2014 西安邀請賽狀壓DP
題意很簡單,求出出口到其他入口之間的最短路徑,再求走完所有管道的距離的最小值。按自己的思路就是tle 看了題解後學習了狀態壓縮動態規劃,再加寬搜求最短距離就ok了。這裡的dp i j 表示以i為起點,在狀態j下的最優值。其中j是用十進位制表示的二進位制,例如 dp表示以2為起點,走了管道0和2的最優...