dp 系列专题(三)

来源:互联网 发布:excel中工龄的算法 编辑:程序博客网 时间:2024/06/14 10:09

LA 4945

#define LIM 1010struct node{int pi,ji;   friend bool operator < (const node&a,const node&b)  {   if( a.ji == b.ji ){   return a.pi<b.pi;   }   return a.ji>b.ji;   }};node a[LIM];int n;bool cmp(const node&ta,const node&tb){if( ta.pi == tb.pi ){return ta.ji<tb.ji;}return ta.pi > tb.pi;}priority_queue<node> PQ;int main() {int T;cin >> T;string s;while (T--) {cin >> n;cin >> s;for (int i = 0; i < n; ++i) {cin >> a[i].pi >> a[i].ji;}sort(a, a + n, cmp);int pet=0,jan=0;int petstart=(s[0]=='P');if( petstart ){pet+=a[0].pi;}for(int i=petstart;i<n;i+=2){PQ.push(a[i]);if( i+1 < n ){PQ.push(a[i+1]);int t=PQ.top().pi;PQ.pop();pet+=t;}}while( !PQ.empty() ){jan+=PQ.top().ji;PQ.pop();}cout<<pet<<" "<<jan<<endl;}return 0;}

LA 4015

#define LIM 510int Head[LIM];struct node{int v,w,next;};node e[LIM*2];int alloc;void addedge(int u,int v,int w){e[alloc].w=w;e[alloc].v=v;e[alloc].next=Head[u];Head[u]=alloc++;}/**************************************************************************************/int N;int go[LIM][LIM];int back[LIM][LIM];int sz[LIM];int In[LIM];void init(){alloc=0;memset(Head,-1,sizeof(Head));for(int i=0;i<=N;++i){for(int j=0;j<=N;++j){go[i][j]=back[i][j]=INF;}}}void dfs(int u,int pre){go[u][1]=0;back[u][1]=0;sz[u]=1;for(int t=Head[u]; t!=-1 ; t=e[t].next){int v=e[t].v;if( v!=pre ){dfs(v,u);sz[u]+=sz[v];for (int i = sz[u]; i >= 2; --i) {for (int j = 1; j <= sz[v] && i - j >= 1; ++j) {if ((go[u][i - j] != INF && back[v][j] != INF)|| (back[u][i - j] != INF && go[v][j] != INF)) {go[u][i] = min(go[u][i],go[u][i - j] + back[v][j] + e[t].w * 2,back[u][i - j] + go[v][j] + e[t].w);}if (back[u][i - j] != INF && back[v][j] != INF) {back[u][i] = min(back[u][i],back[u][i - j] + back[v][j] + e[t].w * 2);}}}}}}int main(){int x,y,z;int cnt=1;    while( scanf("%d",&N) != EOF ){    if( N==0 ) break;    init();    for(int i=1;i<N;++i){    scanf("%d%d%d",&x,&y,&z);    addedge(y,x,z);In[x]++;    }    int root=0;    for(int i=0;i<N;++i){    if( In[i] == 0 ){    root=i;break;    }    }    dfs(root,-1);    printf("Case %d:\n",cnt++);    int Q;    scanf("%d",&Q);    while( Q-- ){    scanf("%d",&x);    for(int i=N;i>=0;--i){    if( x >= min(go[root][i],back[root][i]) ){    printf("%d\n",i);    break;    }    }    }    }    return 0;}

LA 4490
#define LIM 110#define MAXN (1<<8)int a[LIM];int d[LIM][LIM][10][MAXN+10];int main(){int N,K;int cnt=1;while( cin>>N>>K ){if( N==0 && K==0) break;int Allstate=0;for(int i=1;i<=N;++i){cin>>a[i];a[i]-=25;Allstate|=(1<<a[i]);}memset(d,127,sizeof(d));d[0][0][8][0]=0;for (int i = 0; i < N; ++i) {for (int j = 0; j <= min(i, K); ++j) {for (int k = 0; k <= 8; ++k) {for (int s = 0; s < MAXN; ++s) {if (d[i][j][k][s] <= N) {if (a[i + 1] == k) {d[i + 1][j][k][s] = min(d[i + 1][j][k][s],d[i][j][k][s]);} else {d[i + 1][j][a[i + 1]][s | (1 << a[i + 1])] =min(d[i + 1][j][a[i + 1]][s| (1 << a[i + 1])],d[i][j][k][s] + 1);}if (j < K)d[i + 1][j + 1][k][s] = min(d[i + 1][j + 1][k][s], d[i][j][k][s]);}//if( i==0 )//cout<<"d["<<i<<"]["<<j<<"]["<<k<<"]["<<s<<"] "<<d[i][j][k][s]<<endl;}}}}int ans=INF;for (int h = 0; h <= K; ++h) {for (int j = 0; j < MAXN; ++j) {for (int i = 0; i < 8; ++i) {if (d[N][h][i][j] > N)continue;int t = d[N][h][i][j];for (int k = 0; k < 8; ++k) {if ((Allstate & (1 << k)) && !(j & (1 << k))) {t++;}}//cout<<"d["<<N<<"]["<<K<<"]["<<i<<"]["<<j<<"] "<<d[N][K][i][j]<<endl;//cout<<"t "<<t<<endl;ans = min(ans, t);}}}cout<<"Case "<<cnt++<<": "<<ans<<endl<<endl;}return 0;}

uva 11660

#define LIM 35int parent[LIM];int S[LIM];void init(){memset(parent,-1,sizeof(parent));}int Find(int u){return parent[u]==-1?u:parent[u]=Find(parent[u]);}void Union(int u,int v){int r1=Find(u),r2=Find(v);if( r1!=r2 ){if( r1 ==1 ){parent[r2]=r1;S[r1]+=S[r2];}else{parent[r1]=r2;S[r2]+=S[r1];}}}/**************************************************************************************/struct node{int num;int cur;int a[35];node(){ num=0; }bool operator < (const node&t )const {if( cur == t.cur ){for(int i=0;i<num;++i){if( a[i] != t.a[i] ){return a[i]<t.a[i];}}return false;}return cur<t.cur;}};map<node,double> Map;int N,M;double dfs(node x){if( x.num == 0 ) return 0;if( Map.count(x) ){return Map[x];}node tmp;double ans=0.0;for(int i=0;i<x.num;++i){tmp=x;tmp.cur=x.cur+x.a[i];tmp.num=x.num-1;for(int j=i+1;j<x.num;++j){tmp.a[j-1]=x.a[j];}//sort(tmp.a,tmp.a+tmp.num);ans += dfs(tmp)*x.a[i];}ans += N-1;ans /= (N-x.cur);return Map[x]=ans;}int main(){int T;scanf("%d",&T);int cnt=1;while( T-- ){init();Map.clear();scanf("%d%d",&N,&M);for(int i=1;i<=N;++i) S[i]=1;int x,y;for(int i=0;i<M;++i){scanf("%d%d",&x,&y);Union(x,y);}node tmp;tmp.cur=S[1];for(int i=2;i<=N;++i){if( parent[i]==-1 ){tmp.a[tmp.num++]=S[i];}}sort(tmp.a,tmp.a+tmp.num);//cout<<"tmp.cur "<<tmp.cur<<endl;//cout<<"tmp.a "<<endl;//for(int i=0;i<tmp.num;++i){//cout<<"i "<<tmp.a[i]<<endl;//}printf("Case %d: %.6lf\n",cnt++,dfs(tmp));}    return 0;}

LA 4987 目测oj数据有点问题

我的代码(后来下了官方数据,对比了一下,好像是对的,而且这题应该要spj的)

#define LIM 4010struct node{int id,value;bool operator < (const node &x)const {return value < x.value;}};node a[LIM];node b[LIM];i64 d[LIM][LIM];int p[LIM][LIM];int z[LIM][LIM];int Rec[LIM];int bin1(int s,int e,int x){int t,step;int count=e-s;while( count>0 ){t=s;step=count/2;t+=step;if( b[t].value < x ){s=++t; count-=step+1;}else count=step;}return s;}int bin2(int s,int e,int x){int t,step;int count=e-s;e--;while( count>0 ){t=e;step=count/2;t-=step;if( b[t].value > x ){e=--t;count-=step+1;}else count=step;}return e;}void dfs(int x,int y){if( x==0 ) return ;dfs(x-1,p[x][y]);Rec[a[x].id]=b[z[x][y]].id;}int main(){//freopen("64.txt","r",stdin);//freopen("out64.txt","w",stdout);int N,M;while( scanf("%d",&N)!=EOF ){for(int i=1;i<=N;++i){scanf("%d",&a[i].value);a[i].id=i;}scanf("%d",&M);for(int i=1;i<=M;++i){scanf("%d",&b[i].value);b[i].id=i;}sort(a+1,a+N+1);sort(b+1,b+M+1);for(int i=0;i<=N;++i){for(int j=0;j<=M;++j){d[i][j]=INF;}}d[0][0]=0;for(int i=1;i<=N;++i){for(int j=1;j<=i && j<=M;++j){if( d[i-1][j-1]+Abs(a[i].value-b[j].value) < d[i][j] ){d[i][j]=d[i-1][j-1]+Abs(a[i].value-b[j].value);p[i][j]=j-1;z[i][j]=j;}int t1=bin1(1,j+1,a[i].value);//cout<<endl;//cout<<"i "<<i<<" j "<<j<<endl;//cout<<"t1 "<<t1<<endl;if( t1 != j+1 && d[i-1][j]+Abs(a[i].value-b[t1].value) < d[i][j] ){d[i][j]=d[i-1][j]+Abs(a[i].value-b[t1].value);p[i][j]=j;z[i][j]=t1;}t1=bin2(1,j+1,a[i].value);//cout<<"t2 "<<t1<<endl;if( t1 != 0 &&  d[i-1][j]+Abs(a[i].value-b[t1].value) < d[i][j] ){d[i][j]=d[i-1][j]+Abs(a[i].value-b[t1].value);p[i][j]=j;z[i][j]=t1;}}}//for(int i=1;i<=N;++i){//for(int j=1;j<=M;++j){//cout<<endl<<"d["<<i<<"]["<<j<<"] "<<d[i][j]<<endl;//cout<<"p["<<i<<"]["<<j<<"] "<<p[i][j]<<endl;//cout<<"z["<<i<<"]["<<j<<"] "<<z[i][j]<<endl;//}//}printf("%I64d\n",d[N][M]);dfs(N,M);printf("%d",Rec[1]);for(int i=2;i<=N;++i){printf(" %d",Rec[i]);}printf("\n");}return 0;}

LA 4593(完全看了标程写的)

int N;#define LIM 16bool edge[LIM][LIM];int process[110][2];bool NotInclude[1<<LIM];int dp[1<<LIM];int pre[1<<LIM];int color[LIM];map<char,int> M;char hash[LIM];int main(){char str1[10],str2[10];while( scanf("%d",&N) != EOF ){memset(edge,false,sizeof(edge));memset(NotInclude,false,sizeof(NotInclude));M.clear();int Index=0;for(int i=0;i<N;++i){scanf("%s%s",str1,str2);if( !M.count(str1[0]) ){M[str1[0]]=Index;hash[Index]=str1[0];Index++;}if( !M.count(str2[0]) ){M[str2[0]]=Index;hash[Index]=str2[0];Index++;}process[i][0]=M[str1[0]];process[i][1]=M[str2[0]];edge[process[i][0]][process[i][1]]=true;edge[process[i][1]][process[i][0]]=true;}int size=Index;//cout<<"size "<<size<<endl;int ALL=(1<<size);for(int i=0;i<ALL;++i){NotInclude[i]=true;bool flag=false;for(int j=0;j<N;++j){int t=((1<<process[j][0]) | (1<<process[j][1]));if( ( (i|t) == i ) ){flag=true;break;}}if( flag ){NotInclude[i]=false;}}memset(dp,127,sizeof(dp));//if( dp[0] == INF ) cout<<"Yes "<<endl;dp[0]=0;int Fullstate=ALL-1;for(int i=0;i<ALL;++i){if( dp[i] == INF ) continue;int cur=Fullstate&(~i);for(int subset=cur; subset > 0 ; subset=cur&(subset-1)){int newstate= i | subset;if( NotInclude[subset] ){if( dp[newstate] > dp[i] + 1 ){//cout<<"debug "<<endl;//cout<<"dp["<<i<<"] "<<dp[i]<<endl;//cout<<"dp["<<newstate<<"] "<<dp[newstate]<<endl;dp[newstate]=dp[i]+1;pre[newstate]=i;}}}//cout<<"dp["<<i<<"] "<<dp[i]<<endl;}//for(int i=0;i<ALL;++i){//cout<<"dp["<<i<<"] "<<dp[i]<<endl;//}int curstate=Fullstate;int curentcolor=dp[Fullstate];while( curstate>0 ){int prestate=pre[curstate];int dif=curstate&(~prestate);for(int i=0;i<size;++i){if( dif&(1<<i) ){color[i]=curentcolor;}}curstate=prestate;curentcolor--;}printf("%d\n",dp[Fullstate]-2);for(int i=0;i<N;++i){if( color[process[i][0]] < color[process[i][1]] ){printf("%c %c\n",hash[process[i][0]],hash[process[i][1]]);}else{printf("%c %c\n",hash[process[i][1]],hash[process[i][0]]);}}}return 0;}


原创粉丝点击