HDU5772 String problem

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

Total Submission(s): 614    Accepted Submission(s): 282


Problem Description
This is a simple problem about string. Now a string S contains only ‘0’-‘9’. ?? wants to select a subsequence from this string. And makes this subsequence score maximum. The subsequence’s score is calculated as follows:
Score= Value – Total_Cost
The calculation of the Cost is as follows:
If the number of characters x in the subsequence is kx, And the two coefficients are ax,bx,The cost of character x calculated as follows:


{cost[x]=0,kx=0cost[x]=ax(kx1)+bx,kx0

TotalCost=i=09cost[i]

The calculation of the Value is as follows:

Value=0;
for(int i=1;i<=length(substr);++i){
for(int j=1;j<=length(substr);++j){
if(i!=j)
Value+=w[id[i]][id[j]];
}
}

id[i] is the position of the subsequence’s ith character in the original string,for example,if the original string is “13579”,and the subsubquence is “159”,then the array id ={1,3,5}. The w is a weight matrix.
 

 

Input
The first line contains an integer T, denoting the number of the test cases.
For each test case, the first line contains one integers n, the length of a string.
Next line contains the string S.
Next ten lines,each line contains ai,bi,denote the char i’s(0-9) coefficients
Next is a n*n matrix w.
Limits:
T<=20,
0<=n<=100
0<=ai<=bi<=1000
0<=w[i][j]<=50

 

 

Output
Each test output one line “Case #x: y” , where x is the case number ,staring from 1. y is the Maximum score.
 

 

Sample Input
1 3 135 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 0 0 3 1 0 0 4 0 0
 

 

Sample Output
Case #1: 3
Hint
we can choose “15”,id[]={1,3} then Value=w[1][3]+w[3][1]=7, Total_Cost=2+2=4,Score=7-4=3
 

 

Author
FZU
 

 

Source
 

 

Recommend
wange2014
 

 

给定一个只由0~9数字组成的串,要求从其中选出一个价值最大的子序列

 

网络流 最大权闭合子图

连边有点复杂,本质上还是个最大权闭合子图。

可以看出主要关系有三种:

1、选点i和j,可以得到的组合权值

2、选点的代价,代价随着相同数字使用次数累计。

3、子序列包含某个数字就需要付出的代价

如果把第2类点的权值都设成a[i],各自容量为1,第3类点的权值设成-(b[i]-a[i]),各自容量为INF,选2就必须选对应的3,那么代价问题就解决了。

割1舍弃收益,割2+3舍弃数字,显然是一个最大权闭合子图问题。

 

  1 /*by SilverN*/
  2 #include<algorithm>
  3 #include<iostream>
  4 #include<cstring>
  5 #include<cstdio>
  6 #include<cmath>
  7 #include<vector>
  8 #include<queue>
  9 using namespace std;
 10 const int INF=0x3f3f3f3f;
 11 const int mxn=100010;
 12 int read(){
 13     int x=0,f=1;char ch=getchar();
 14     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 15     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
 16     return x*f;
 17 }
 18 inline int min(int a,int b){return a<b?a:b;}
 19 struct edge{
 20     int v,nxt,f;
 21 }e[mxn<<1];
 22 int hd[mxn],mct=1;
 23 void add_edge(int u,int v,int w){
 24     e[++mct].v=v;e[mct].nxt=hd[u];e[mct].f=w;hd[u]=mct;return;
 25 }
 26 void insert(int u,int v,int w){
 27     add_edge(u,v,w);add_edge(v,u,0);
 28     return;
 29 }
 30 int S,T;
 31 int d[mxn];
 32 queue<int>q;
 33 bool BFS(){
 34     memset(d,0,sizeof d);
 35     q.push(S);d[S]=1;
 36     while(!q.empty()){
 37         int u=q.front();q.pop();
 38         for(int i=hd[u];i;i=e[i].nxt){
 39             int v=e[i].v;
 40             if(!d[v] && e[i].f){
 41                 d[v]=d[u]+1;
 42                 q.push(v);
 43             }
 44         }
 45     }
 46     return d[T];
 47 }
 48 int DFS(int u,int lim){
 49     if(u==T)return lim;
 50     int f=0,tmp;
 51     for(int i=hd[u];i;i=e[i].nxt){
 52         int v=e[i].v;
 53         if(d[v]==d[u]+1 && e[i].f && (tmp=DFS(v,min(lim,e[i].f)))){
 54             e[i].f-=tmp;
 55             e[i^1].f+=tmp;
 56             lim-=tmp;
 57             f+=tmp;
 58             if(!lim)return f;
 59         }
 60     }
 61     d[u]=0;
 62     return f;
 63 }
 64 int Dinic(){
 65     int res=0;
 66     while(BFS()){res+=DFS(S,INF);}
 67     return res;
 68 }
 69 int n,m,ed,cnt;
 70 char s[200];
 71 int mp[120][120];
 72 int a[11],b[11];
 73 void Build(){
 74     ed=n*(n-1)/2;cnt=0;
 75     S=0;T=ed+n+10+1;
 76     int i,j;
 77     for(i=1;i<=n;i++){
 78         for(j=i+1;j<=n;j++){
 79             ++cnt;
 80             insert(S,cnt,mp[i][j]+mp[j][i]);
 81             insert(cnt,ed+i,INF);
 82             insert(cnt,ed+j,INF);
 83         }
 84     }
 85     for(i=1;i<=n;i++){
 86         int c=s[i]-'0'+1;
 87         insert(ed+i,T,a[c-1]);
 88         insert(ed+i,ed+n+c,INF);
 89     }
 90     for(i=0;i<=9;i++){
 91         int u=ed+n+i+1;
 92         insert(u,T,b[i]-a[i]);
 93     }
 94     return;
 95 }
 96 void init(){
 97     memset(hd,0,sizeof hd);mct=1;
 98     return;
 99 }
100 int cas;
101 int main(){
102     int i,j,u,v;
103     cas=read();int cct=0;
104     while(cas--){
105         int ans=0;
106         init();
107         n=read();
108         scanf("%s",s+1);
109         for(i=0;i<=9;i++){a[i]=read();b[i]=read();}
110         for(i=1;i<=n;i++)
111             for(j=1;j<=n;j++)
112                 mp[i][j]=read(),ans+=mp[i][j];
113         Build();
114         ans-=Dinic();
115         printf("Case #%d: %d\n",++cct,ans);
116     }
117     return 0;
118 }

 

posted @ 2017-03-28 10:46  SilverNebula  阅读(179)  评论(0编辑  收藏  举报
AmazingCounters.com