Solved | ID | PID | Title | Accepted | Submit |
---|---|---|---|---|---|
A | 2407 | Impasse (+) | 0 | 0 | |
B | 2410 | Mine Number | 3 | 19 | |
C | 2412 | Fruit Ninja I | 4 | 19 | |
D | 2414 | An interesting game | 1 | 6 | |
E | 2416 | Fruit Ninja II | 8 | 13 | |
F | 2415 | Chess | 1 | 1 | |
G | 2413 | n a^o7 ! | 10 | 14 | |
H | 2411 | Pixel density | 9 | 36 | |
I | 2409 | The Best Seat in ACM Contest | 10 | 20 | |
J | 2408 | Pick apples | 7 | 45 |
:http://www.sdutacm.org/sdutoj/showproblem.php?pid=2407&cid=1744
http://www.sdutacm.org/sdutoj/problem.php?action=showproblem&problemid=2410
只要是第一行确定了,全部棋局也就确定了,dfs搜索第一行的情况,然后后面的直接根据上一行而定,这样最后就能得出整个矩阵了,第一行最多20个,也就是复杂度为2^20,不会超时,并且中间还会有剪枝。
但是苦逼的是当时模拟的时候感觉dfs没什么用,只要第一行确定了其他就能确定的话,我直接二进制分解获得第一行就行了,但是这样做了好久,却不是TL就是WR,至今不知道为何,以后有时间了再看吧。。。(顺便也贴下第一次二进制分解的错误方法。。)
#include <iostream> #include <cstdio> #include <string> #include <cstring> #define MAX 500 using namespace std; char ch[100][100],res[100][100]; int T,n,m; int dir[][2]= {{-1,0},{1,0},{0,-1},{0,1},{0,0}}; int mark=0; bool OK(int x,int y){ int tempx,tempy; for(int i=0;i<5;i++){ tempx=x+dir[i][0],tempy=y+dir[i][1]; if( (tempx<0 || tempx>=n || tempy<0 || tempy>=m) || ch[tempx][tempy]>='1') continue; else return false; } return true; } void update(int x,int y,int num){ for(int i=0;i<4;i++){ int tempx=dir[i][0]+x , tempy=dir[i][1]+y; if( tempx >= 0 && tempx < n && tempy>=0 &&tempy<m ) ch[tempx][tempy]+=num; } ch[x][y]+=num; } void printres(){ for(int i=0; i<n; i++) { for(int j=0; j<m; j++) printf("%c",res[i][j]); printf("\n"); } } bool judge(){ for(int i=0;i<m;i++) if(ch[n-1][i]!='0') return false; return true; } void dfs(int x,int y){ if(y>=m) x++,y=0; if( x==n && y==0 ){ if(judge()){ printres(); mark=1; } } if( x<0 || x>=n || mark==1) return ; if(x==0){ if( OK(x,y) ){ update(x,y,-1); res[x][y]='*'; dfs(x,y+1); update(x,y,1); res[x][y]='?'; } res[x][y]='.'; dfs(x,y+1); return ; } if( ch[x-1][y] !='0' && ch[x-1][y] !='1' ) return ; if(ch[x-1][y]=='1'){ res[x][y]='*'; update(x,y,-1); dfs(x,y+1); update(x,y,1); res[x][y]='?'; } else{ res[x][y]='.'; dfs(x,y+1); } return ; } int main () { char dev[100]; int coun=1; scanf("%d",&T); while(T--) { mark=0; scanf("%d%d",&n,&m); for(int i=0; i<n; i++) scanf("%s",&ch[i]); printf("Case %d:\n",coun++); dfs(0,0); } return 0; }
#include <iostream> #include <cstdio> #include <string> #include <cstring> #define MAX 500 using namespace std; char ch[100][100],temp[100][100],res[100][100]; int T,n,m; int dir[][2]= {{-1,0},{1,0},{0,-1},{0,1}}; bool Ok(int tempm){ return temp[0][tempm]=='0' || (tempm!=0&&temp[0][tempm-1]=='0') || (tempm+1<m&&temp[0][tempm+1]=='0'); ///|| (1<n&&temp[1][tempm]=='0') } int main () { char dev[100]; int coun=1; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); for(int i=0; i<n; i++) scanf("%s",&ch[i]); int x=(1<<m); printf("Case %d:\n",coun++); int last=n-1; for(int ss=x-1; ss>=0; ss--) { int mark=1; int tempm=m-1; for(int j=0; j<m; j++) res[0][j]='.'; for(int i=0; i<=n-1; i++) strcpy(temp[i],ch[i]); int tempss=ss; for(; tempss>0; tempm--) { if(tempss%2) { res[0][tempm]='*'; if(Ok(tempm)) { mark = 0; last=2; break; } temp[0][tempm]--; if(tempm-1>=0) temp[0][tempm-1]--; if(tempm+1<m) temp[0][tempm+1]--; if(1<n) temp[1][tempm]--; } tempss/=2; } for(int i=1; i<n && mark ; i++) for(int j=0; j<m && mark; j++) { if( temp[i-1][j]!='0' && temp[i-1][j]!='1' ) { mark=0; last=min(n-1,i+2); break; } res[i][j]='.'; if(temp[i-1][j]=='1') { res[i][j]='*'; for(int xxx=0; xxx<4; xxx++) if(i+dir[xxx][0]>=0 && i+dir[xxx][0]<m && j+dir[xxx][1]>=0 && j+dir[xxx][1]<m) { if(temp[ i+dir[xxx][0] ][ j+dir[xxx][1] ]<='0') { mark=0; last=min(n-1,i+2); break; } temp[ i+dir[xxx][0] ][ j+dir[xxx][1] ]--; } temp[i][j]--; } } if(mark==1) { for(int i=0; i<m&&mark; i++) ///判断最后一行 if(temp[n-1][i]!='0') mark=0,last=n-1; for(int i=0; i<n&&mark; i++) { for(int j=0; j<m; j++) printf("%c",res[i][j]); printf("\n"); } if(mark){ break; } } } } return 0; }
http://www.sdutacm.org/sdutoj/problem.php?action=showproblem&problemid=2412
题意:一个切水果游戏。每秒出现一些水果,它们都在一条线上,有好水果和坏水果,好的可以加分,坏的减分,每次连续切好水果三个以上可以分数加倍。每秒只能切一次,每切一次要间隔m秒。问最多得多少分。
暴力+dp 开始的时候没想到,没什么头绪,因为每一次需要间隔一定的时间,但是没考虑到每个时间点t内的最大值是可求得,这样直接DP就好了。。。
#include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<iostream> #include<algorithm> #include<vector> #include<map> #include<queue> #include<stack> #include<string> #include<map> #include<set> #include<ctime> #define eps 1e-6 #define MAX 10010 #define INF 0x3f3f3f3f #define LL long long #define pii pair<string,int> #define rd(x) scanf("%d",&x) #define rd2(x,y) scanf("%d%d",&x,&y) using namespace std; struct Stru{ int time; int x; int mm; }pos[MAX]; int arr[MAX]; int dp[MAX]; bool cmp(Stru a,Stru b){ if(a.time!=b.time) return a.time<b.time; return a.x<b.x; } int main() { int T; scanf("%d",&T); int n,m,temp,Case=1; while(T--){ scanf("%d%d",&n,&m); for(int i=0;i<n;i++){ scanf("%d%d%d",&pos[i].time,&temp,&pos[i].x); pos[i].mm = ( temp == 0 ? 1 : -1); } memset(arr,0,sizeof(arr)); sort(pos,pos+n,cmp); int start=pos[0].time,sum=0,seque=0,mmax=0;///start:当前正在判断的时间标志 ///sum:在start秒里到当前位置能获得的最大的分数 /// 注意!如果seque统计需要加倍时在seque清0之前是没有Double分数的) ///seque:连续的个数(用来最后统计Double分数的) ///mmax:当前秒获得的最大分数 ///该部分统计分数的精髓:http://blog.csdn.net/u014665013/article/details/50094365 for(int i=0;i<n;i++){ ///暴力求每个时间t能获得的最大分数(连续区间最大值) if(pos[i].time==start){ if(pos[i].mm==-1){ if(seque>=3) sum+=seque; seque=0; } else seque++; sum += pos[i].mm; if ( sum+(seque>=3?seque:0) > mmax) mmax = sum+(seque>=3?seque:0); else if (sum < 0) sum = 0; } else{ arr[ pos[i-1].time ] = mmax; start=pos[i].time; sum=0,seque=0; if(pos[i].mm==1) sum=1,seque=1; mmax=sum; } } arr[pos[n-1].time]=mmax; dp[0]=0; for(int i=1;i<=pos[n-1].time;i++){ ///dp最大值 转移方程 dp[i]=dp[i-1],dp[i-m-1]+arr[i] if(i>m+1) dp[i]=max(dp[i-1],dp[i-m-1]+arr[i]); else dp[i]=max(dp[i-1],arr[i]); } printf("Case %d: %d\n",Case++,dp[pos[n-1].time]); } return 0; }
D An interesting game
http://www.sdutacm.org/sdutoj/showproblem.php?pid=2414&cid=1744最小费用最大流,开始ps用贪心,每次找出最大高度或者最小高度的插入,然后如果最大高度的能插入则插最大的,否则就插小的,(注意插入时候需要贪心两步)感觉是可以的,但是最终问题出在哪里好像还不知道。
一个不错的网址:http://www.hardbird.net/%E5%B1%B1%E4%B8%9C%E7%9C%81%E7%AC%AC%E4%B8%89%E5%B1%8A%E7%9C%81%E8%B5%9B-c-%E9%A2%98-an-interesting-game%E8%B4%B9%E7%94%A8%E6%B5%81/
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <vector> #include <queue> using namespace std; const int maxn=2200; const int oo=0x3f3f3f3f; struct Edge { int u, v, cap, flow, cost;Edge(){} Edge(int u, int v, int cap, int flow, int cost):u(u), v(v), cap(cap), flow(flow), cost(cost) {} }; struct MCMF { int n, m, s, t; vector<Edge> edge; vector<int> G[maxn]; int inq[maxn], d[maxn], p[maxn], a[maxn]; void init(int n) { this->n=n; for(int i=0; i<n; i++) G[i].clear(); edge.clear(); } void AddEdge(int u, int v, int cap, int cost) { edge.push_back(Edge(u, v, cap, 0, cost)); edge.push_back(Edge(v, u, 0, 0, -cost)); m=edge.size(); G[u].push_back(m-2); G[v].push_back(m-1); } bool spfa(int s, int t, int& flow, int& cost) { memset(d, 0x3f, sizeof d); memset(inq, 0, sizeof inq); d[s]=0, inq[s]=1, p[s]=0, a[s]=oo; queue<int> q; q.push(s); while(!q.empty()) { int u=q.front(); q.pop(); inq[u]=0; for(int i=0; i<G[u].size(); i++) { Edge& e=edge[G[u][i]]; if(e.cap>e.flow && d[e.v]>d[u]+e.cost) { d[e.v]=d[u]+e.cost; p[e.v]=G[u][i]; a[e.v]=min(a[u], e.cap-e.flow); if(!inq[e.v]) { q.push(e.v); inq[e.v]=1; } } } } if(d[t]==oo)return false; flow+=a[t]; cost+=d[t]*a[t]; int u=t; while(u!=s) { edge[p[u]].flow+=a[t]; edge[p[u]^1].flow-=a[t]; u=edge[p[u]].u; } return true; } int MinCost(int s, int t) { int flow=0, cost=0; while(spfa(s, t, flow, cost)); return cost; } } net; int a[maxn], b[maxn]; int main() { int T, kase=0; scanf("%d", &T); while(T--) { int n, m, k, ans=0; scanf("%d%d%d", &n, &m, &k); net.init(n+100); memset(b, 0, sizeof b); for(int i=0; i<n; i++) scanf("%d", a+i); for(int i=0; i<m; i++) { int x; scanf("%d", &x); b[x]++; } for(int i=1; i<n; i++) { ans+=abs(a[i]-a[i-1]); net.AddEdge(0, i, 1, 0); for(int j=0; j<=30; j++) if(b[j]) { int dis=abs(a[i]-j)+abs(a[i-1]-j)-abs(a[i]-a[i-1]); net.AddEdge(i, n+j, 1, -dis); } } int S=n+50, T=S+1; for(int i=0; i<=30; i++) if(b[i]) net.AddEdge(i+n, T, b[i], 0); net.AddEdge(S, 0, k, 0); printf("Case %d: %d\n", ++kase, ans-net.MinCost(S, T)); } return 0; }
另一个
/* SPFA版费用流 最小费用最大流,求最大费用最大流只需要取相反数,结果取相反数即可。 点的总数为N,点的编号0~N-1 */ #include<iostream> #include<stdio.h> #include<string.h> #include<queue> #include<algorithm> using namespace std; const int MAXN=1500; const int MAXM=80000; const int INF=0x3f3f3f3f; struct Edge{ int to,next,cap,flow,cost; }edge[MAXM]; int head[MAXN],tol; int pre[MAXN],dis[MAXN]; bool vis[MAXN]; int N;//节点总个数,节点编号从0~N-1 void init(int n){ N=n; tol=0; memset(head,-1,sizeof(head)); } void addedge(int u,int v,int cap,int cost){ edge[tol].to=v; edge[tol].cap=cap; edge[tol].cost=cost; edge[tol].flow=0; edge[tol].next=head[u]; head[u]=tol++; edge[tol].to=u; edge[tol].cap=0; edge[tol].cost=-cost; edge[tol].flow=0; edge[tol].next=head[v]; head[v]=tol++; } bool spfa(int s,int t){ queue<int>q; for(int i=0;i<N;i++){ dis[i]=INF; vis[i]=false; pre[i]=-1; } dis[s]=0; vis[s]=true; q.push(s); while(!q.empty()){ int u=q.front(); q.pop(); vis[u]=false; for(int i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].to; if(edge[i].cap>edge[i].flow&&dis[v]>dis[u]+edge[i].cost){ dis[v]=dis[u]+edge[i].cost; pre[v]=i; if(!vis[v]){ vis[v]=true; q.push(v); } } } } if(pre[t]==-1)return false; else return true; } //返回的是最大流,cost存的是最小费用 int minCostMaxflow(int s,int t,int &cost){ int flow=0; cost=0; while(spfa(s,t)){ int Min=INF; for(int i=pre[t];i!=-1;i=pre[edge[i^1].to]){ if(Min>edge[i].cap-edge[i].flow) Min=edge[i].cap-edge[i].flow; } for(int i=pre[t];i!=-1;i=pre[edge[i^1].to]){ edge[i].flow+=Min; edge[i^1].flow-=Min; cost+=edge[i].cost*Min; } flow+=Min; } return flow; } int main(){ int T; int N2,M,K; int X[1005],Y[1005]; int YNum[40]; int i,j; int sp,sp2;//源点,源点2 int sc;//汇点 int sum; int tmp; int mi_cost; int ma_flow; int ca=0; scanf("%d",&T); while(T--){ scanf("%d%d%d",&N2,&M,&K); init(N2+50); for(i=0;i<N2;++i){ scanf("%d",&X[i]); } memset(YNum,0,sizeof(YNum)); for(i=0;i<M;++i){ scanf("%d",&Y[i]); ++YNum[Y[i]]; } sum=0; for(i=0;i<N2-1;++i){//初始值 sum=sum+abs(X[i]-X[i+1]); } sp=N2+40; for(i=0;i<N2-1;++i){//加边 addedge(sp,i,1,0);//源点到空隙 for(j=0;j<=30;++j){ if(YNum[j]){ tmp=abs(X[i]-j)+abs(X[i+1]-j)-abs(X[i]-X[i+1]); addedge(i,N2+j,1,-tmp);//空隙到M个山丘 } } } sp2=N2+41; sc=N2+42; addedge(sp2,sp,K,0); for(i=0;i<=30;++i){ if(YNum[i]){ addedge(N2+i,sc,YNum[i],0); } } ma_flow=minCostMaxflow(sp2,sc,mi_cost); printf("Case %d: %d\n",++ca,sum-mi_cost); } return 0; }
#include <iostream> #include <stdio.h> #include <cmath> using namespace std; int main() { int T; scanf("%d",&T); int i; for(i=1;i<=T;i++) { int a,b,h; scanf("%d%d%d",&a,&b,&h); double V; V=(4.0/3)*M_PI*a*b*b; if(h>=b) { printf("Case %d: %.3lf\n",i,V); } else { double v=M_PI*a*b*(b-h)-M_PI*(1.0*a/b)*(1.0/3)*(b*b*b-h*h*h); if(V-v-v>0) printf("Case %d: %.3lf\n",i,V-v); else printf("Case %d: %.3lf\n",i,v); } } return 0; }
E:Fruit Ninja II
#include <iostream> #include <stdio.h> #include <cmath> using namespace std; int main() { int T; scanf("%d",&T); int i; for(i=1;i<=T;i++) { int a,b,h; scanf("%d%d%d",&a,&b,&h); double V; V=(4.0/3)*M_PI*a*b*b; if(h>=b) { printf("Case %d: %.3lf\n",i,V); } else { double v=M_PI*a*b*(b-h)-M_PI*(1.0*a/b)*(1.0/3)*(b*b*b-h*h*h); if(V-v-v>0) printf("Case %d: %.3lf\n",i,V-v); else printf("Case %d: %.3lf\n",i,v); } } return 0; }
#include <iostream> #include <cstdio> #include <string> #include <cstring> #define MAX 500 using namespace std; int main (){ char temp1[MAX],temp2[MAX],str[MAX]; strcpy(temp1," n5!wpuea^o7!usimdnaevoli"); strcpy(temp2," usimdnaevolin5!wpuea^o7!"); int Len = strlen(temp1); int T; scanf("%d",&T); getchar(); int coun=1; while(T--){ gets(str); int len=strlen(str); for(int i=0,j=0;i<len;i++){ for(j=0;j<Len;j++) if(str[i]==temp1[j]) break; if(j<Len) str[i]=temp2[j]; } printf("Case %d: ",coun++); for(int i=len-1;i>=0;i--) printf("%c",str[i]); printf("\n"); } return 0; }
#include<iostream> #include<stdio.h> #include<string.h> #include<math.h> using namespace std; char str[12345]; char str1[12345]; char str2[12345]; char num1[12345]; char num2[12345]; char num3[12345]; int main(){ int T; int i; int len; int len1,len2; int p1,p2; int p3,p4; int len_num1,len_num2,len_num3; int j; double a,a1,a2,b,b1,b2,c,c1,c2; int p5; double Dp; double ans; int ca=0; int p6,p7; scanf("%d",&T); getchar(); //scanf("%[^\n]",str); //cout<<str<<endl; while(T--){ scanf("%[^\n]",str); getchar(); //printf(""); //printf("%s\n",str); //cout<<str<<endl; len=strlen(str); //cout<<len<<endl; len1=0; len2=0; len_num1=0; len_num2=0; len_num3=0; for(i=0;i<len;++i){ if(str[i]=='i'){ if(str[i+1]=='n'&&str[i+2]=='c'&&str[i+3]=='h'&& str[i+4]=='e'&&str[i+5]=='s'&&str[i+6]==' '){ p1=i; j=i-1; while(str[j]==' '){ --j; } while(str[j]!=' '){ num1[len_num1++]=str[j--]; } while(str[j]==' '){ --j; } p3=j; } } if(str[i]=='*'){ if(i>=1&&'0'<=str[i-1]&&str[i-1]<='9'){ if('0'<=str[i+1]&&str[i+1]<='9'){ p2=i; j=i-1; while(str[j]!=' '){ num2[len_num2++]=str[j--]; } j=i+1; while(str[j]!=' '){ num3[len_num3++]=str[j++]; } while(str[j]==' '){ ++j; } p4=j; } } } } for(i=0;i<=p3;++i){ if(str[i]!=' '){ break; } } str1[len1++]=str[i++]; for(;i<=p3;++i){ if(str[i]==' '&&str1[len1-1]==' '){ continue; } str1[len1++]=str[i]; } str1[len1]='\0'; for(i=p4;i<len;++i){ if(str[i]==' '&&str2[len2-1]==' '){ continue; } if('a'<=str[i]&&str[i]<='z'){ str2[len2++]=str[i]; } else if('A'<=str[i]&&str[i]<='Z'){ str2[len2++]=str[i]+32; } else{ str2[len2++]=str[i]; } } str2[len2]='\0'; for(i=len2-1;i>=0;--i){ if(str2[i]!=' '){ len2=i+1; break; } } str2[i+1]='\0'; /* cout<<str1<<endl; cout<<str2<<endl; cout<<num1<<endl; cout<<num2<<endl; cout<<num3<<endl; */ p5=-1; for(i=0;i<len_num1;++i){ if(num1[i]=='.'){ p5=i; break; } } a=0; a1=0; a2=0; if(p5==-1){ for(i=0;i<len_num1;++i){ a1=a1+(num1[i]-'0')*pow(10,i); } } else{ //a2=0; for(i=0;i<p5;++i){ a2=a2/10+(num1[i]-'0')/10.0; } //a1=0; for(i=p5+1;i<len_num1;++i){ a1=a1+(num1[i]-'0')*pow(10,(i-(p5+1))); } } //cout<<a2<<endl; //cout<<a1<<endl; a=a1+a2; //cout<<"a:"<<a<<endl; if(a==0){ printf("Case %d: The %s of %s's PPI is %.2f.\n",++ca,str2,str1,0.0); continue; } p6=-1; for(i=0;i<len_num2;++i){ if(num2[i]=='.'){ p6=i; break; } } if(p6==-1){ b=0; for(i=0;i<len_num2;++i){ b=b+(num2[i]-'0')*pow(10,i); } } else{ b=0; b1=0; b2=0; //cout<<p6<<"***"<<endl; for(i=0;i<p6;++i){ b2=b2/10+(num2[i]-'0')/10.0; //cout<<"##"<<b2<<endl; } for(i=p6+1;i<len_num2;++i){ b1=b1+(num2[i]-'0')*pow(10,(i-(p6+1))); } /* for(i=p5-1;i>=0;--i){ a2=a2/10+(num1[i]-'0')/10.0; } //a1=0; for(i=p5+1;i<len_num1;++i){ a1=a1+(num1[i]-'0')*pow(10,(i-(p5+1))); } */ b=b1+b2; //cout<<"b:"<<b<<endl; } p7=-1; for(i=0;i<len_num3;++i){ if(num3[i]=='.'){ p7=i; break; } } if(p7==-1){ c=0; for(i=0;i<len_num3;++i){ c=c*10+(num3[i]-'0'); } } else{ c=0; c1=0; c2=0; for(i=0;i<p7;++i){ //c2=c2/10+(num3[i]-'0')/10.0; c1=c1*10+(num3[i]-'0'); //cout<<"##"<<c2<<endl; } for(i=p7+1;i<len_num3;++i){ //c1=c1+(num3[i]-'0')*pow(10,(i-(p7+1))); c2=c2/10+(num3[i]-'0')/10.0; } c=c1+c2; //cout<<"c:"<<c<<endl; } //cout<<b<<endl; //cout<<c<<endl; Dp=sqrt(b*b+c*c); ans=Dp/a; //cout<<ans<<endl; printf("Case %d: The %s of %s's PPI is %.2f.\n",++ca,str2,str1,ans); } /* 33 ip 00300.00600 inches 00500.00600*00700.00800 IPHone 2 iPhone 4S 3.5 inches 960*640 PHONE The new iPad 0009.7 inches 2048*1536 PAD */ return 0; }
I:The
Best Seat in ACM Contest
#include<iostream> #include<stdio.h> #include<string.h> using namespace std; int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}}; int main(){ int T; int N,M; int s[25][25]; int v[25][25]; int i,j; int a,b; int ma,ma_i,ma_j; int ca=0; int k; scanf("%d",&T); while(T--){ scanf("%d%d",&N,&M); for(i=0;i<N;++i){ for(j=0;j<M;++j){ scanf("%d",&s[i][j]); } } memset(v,0,sizeof(v)); for(i=0;i<N;++i){ for(j=0;j<M;++j){ for(k=0;k<4;++k){ a=i+dir[k][0]; b=j+dir[k][1]; if(a<0||b<0||a>=N||b>=M){ v[i][j]-=1; continue; } if(s[a][b]>s[i][j]){ v[i][j]=v[i][j]+(s[a][b]-s[i][j]); } else{ v[i][j]=v[i][j]-(s[i][j]-s[a][b]); } } } } ma=v[0][0]; ma_i=0; ma_j=0; for(i=0;i<N;++i){ for(j=0;j<M;++j){ if(v[i][j]>=ma){ ma=v[i][j]; ma_i=i; ma_j=j; } } } printf("Case %d: %d %d %d\n",++ca,ma,ma_i+1,ma_j+1); } return 0; } /************************************** Problem id : SDUT OJ I User name : 666777 Result : Accepted Take Memory : 512K Take Time : 0MS Submit Time : 2016-04-30 13:53:18 **************************************/
#include<iostream> #include<stdio.h> #include<algorithm> #include<string.h> using namespace std; struct node{ long long S; long long P; double q; }a[3]; bool cmp(node a,node b){ return a.q>b.q; } int main(){ int T; long long V; long long sum; long long dp[6000]; long long tmp; int i,j; int ca=0; scanf("%d",&T); while(T--){ scanf("%lld%lld",&a[0].S,&a[0].P); a[0].q=(double)(a[0].P)/a[0].S; //cout<<a[0].q<<endl; scanf("%lld%lld",&a[1].S,&a[1].P); a[1].q=(double)(a[1].P)/a[1].S; //cout<<a[1].q<<endl; scanf("%lld%lld",&a[2].S,&a[2].P); a[2].q=(double)(a[2].P)/a[2].S; //cout<<a[2].q<<endl; scanf("%lld",&V); sort(a,a+3,cmp); sum=V%a[0].S; for(i=1;;++i){ if(a[0].S*i>=5000){ break; } } sum=sum+a[0].S*i; memset(dp,0,sizeof(dp)); for(i=0;i<3;++i){ for(j=a[i].S;j<=sum;++j){ tmp=dp[j-a[i].S]+a[i].P; if(tmp>dp[j]){ dp[j]=tmp; } } } for(i=sum;;--i){ if(dp[i]>0){ break; } } printf("Case %d: %lld\n",++ca,((V-sum)/a[0].S)*a[0].P+dp[i]); } return 0; } /************************************** Problem id : SDUT OJ J User name : 666777 Result : Accepted Take Memory : 556K Take Time : 0MS Submit Time : 2016-04-30 17:44:39 **************************************/