HDU5900 QSC and Master(区间DP + 最小费用最大流)
題目
Source
http://acm.hdu.edu.cn/showproblem.php?pid=5900
Description
Every school has some legends, Northeastern University is the same.
Enter from the north gate of Northeastern University,You are facing the main building of Northeastern University.Ninety-nine percent of the students have not been there,It is said that there is a monster in it.
QSCI am a curious NEU_ACMer,This is the story he told us.
It’s a certain period,QSCI am in a dark night, secretly sneaked into the East Building,hope to see the master.After a serious search,He finally saw the little master in a dark corner. The master said:
“You and I, we're interfacing.please solve my little puzzle!
There are N pairs of numbers,Each pair consists of a key and a value,Now you need to move out some of the pairs to get the score.You can move out two continuous pairs,if and only if their keys are non coprime(their gcd is not one).The final score you get is the sum of all pair’s value which be moved out. May I ask how many points you can get the most?
The answer you give is directly related to your final exam results~The young man~”
QSC is very sad when he told the story,He failed his linear algebra that year because he didn't work out the puzzle.
Could you solve this puzzle?
(Data range:1<=N<=300
1<=Ai.key<=1,000,000,000
0<Ai.value<=1,000,000,000)
Input
First line contains a integer T,means there are T(1≤T≤10) test case。
Each test case start with one integer N . Next line contains N integers,means Ai.key.Next line contains N integers,means Ai.value.
Output
For each test case,output the max score you could get in a line.
Sample Input
3
3
1 2 3
1 1 1
3
1 2 4
1 1 1
4
1 3 4 3
1 1 1 1
Sample Output
0
2
0
?
分析
題目大概說給N個<key,value>二元組,每次可以取出相鄰的且其key的GCD不為1的兩個二元組,并獲得二者value之和的價值,問能取到的最大價值是多少?
?
注意取掉后就左右兩部分就合并在一起。。
顯然考慮區(qū)間DP:
- dp[i][j]表示下標i到j的二元組全部消除能獲得的最大價值
- 通過枚舉k(i<=k<j)從max(dp[i][k]+dp[k+1][j])轉(zhuǎn)移;此外如果key[i]等于key[j],還能從dp[i+1][j-1]+value[i]+value[j]轉(zhuǎn)移
于是這樣就能求出所有能消除的全部區(qū)間以及消除它們能獲得的最大價值,而問題就是要從這些區(qū)間取出不重疊的幾個使得價值和最大。
這個可以用最小費用最大流解,區(qū)間k覆蓋。。也能再dp一次,dp[i]表示考慮坐標點在i之前的區(qū)間所能獲得的最大價值。。
?
代碼
#include<cstdio> #include<cstring> #include<queue> #include<algorithm> using namespace std; #define INF (1LL<<60) #define MAXN 333 #define MAXM 3333*666 struct Edge{int u,v,next;long long cap,cost; }edge[MAXM]; int head[MAXN]; int NV,NE,vs,vt;void addEdge(int u,int v,long long cap,long long cost){edge[NE].u=u; edge[NE].v=v; edge[NE].cap=cap; edge[NE].cost=cost;edge[NE].next=head[u]; head[u]=NE++;edge[NE].u=v; edge[NE].v=u; edge[NE].cap=0; edge[NE].cost=-cost;edge[NE].next=head[v]; head[v]=NE++; } bool vis[MAXN]; long long dis[MAXN]; int pre[MAXN]; bool SPFA(){for(int i=0; i<NV; ++i){vis[i]=0;dis[i]=INF;}vis[vs]=1;dis[vs]=0;queue<int> que;que.push(vs);while(!que.empty()){int u=que.front(); que.pop();for(int i=head[u]; i!=-1; i=edge[i].next){int v=edge[i].v;if(edge[i].cap && dis[v]>dis[u]+edge[i].cost){dis[v]=dis[u]+edge[i].cost;pre[v]=i;if(!vis[v]){vis[v]=1;que.push(v);}}}vis[u]=0;}return dis[vt]!=INF; } long long MCMF(){long long res=0;while(SPFA()){long long flow=INF,cost=0;for(int u=vt; u!=vs; u=edge[pre[u]].u){flow=min(flow,edge[pre[u]].cap);}for(int u=vt; u!=vs; u=edge[pre[u]].u){edge[pre[u]].cap-=flow;edge[pre[u]^1].cap+=flow;cost+=flow*edge[pre[u]].cost;}res+=cost;}return res; }long long d[MAXN][MAXN];long long gcd(long long a,long long b){if(b==0) return a;return gcd(b,a%b); }bool ok[MAXN][MAXN];long long key[MAXN],val[MAXN];int main(){int t,n;scanf("%d",&t);while(t--){scanf("%d",&n);for(int i=1; i<=n; ++i){scanf("%I64d",key+i);}for(int i=1; i<=n; ++i){scanf("%I64d",val+i);}memset(ok,0,sizeof(ok));for(int i=1; i<=n; ++i){for(int j=i+1; j<=n; ++j){if(gcd(key[i],key[j])==1) continue;ok[i][j]=1;ok[j][i]=1;}}for(int i=1; i<=n; ++i){for(int j=1; j<=n; ++j){d[i][j]=-INF;}}for(int len=2; len<=n; ++len){for(int i=1; i+len-1<=n; ++i){if(ok[i][i+len-1] && len==2){d[i][i+len-1]=val[i]+val[i+len-1];continue;}if(ok[i][i+len-1]) d[i][i+len-1]=max(d[i][i+len-1],val[i]+val[i+len-1]+d[i+1][i+len-1-1]);for(int j=0; j<len-1; ++j){d[i][i+len-1]=max(d[i][i+len-1],d[i][i+j]+d[i+j+1][i+len-1]);}}}long long ans=0;vs=0; vt=n+2; NV=vt+1; NE=0;memset(head,-1,sizeof(head));addEdge(vs,1,1,0);addEdge(n+1,vt,1,0);for(int i=1; i<=n; ++i){addEdge(i,i+1,INF,0);}for(int i=1; i<=n; ++i){for(int j=i+1; j<=n; ++j){if(d[i][j]!=-INF){addEdge(i,j+1,1,-d[i][j]);}}}printf("%I64d\n",-MCMF());} }?
轉(zhuǎn)載于:https://www.cnblogs.com/WABoss/p/5883182.html
總結(jié)
以上是生活随笔為你收集整理的HDU5900 QSC and Master(区间DP + 最小费用最大流)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: js(javascript)与OC(Ob
- 下一篇: 有些事儿,工程师可能今生仅此一次