标签:ali esc ret arch AC one 错误 bool 一个
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 11448 Accepted Submission(s): 5466
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 struct subject{ 6 char name[106]; 7 int de,ne; 8 }s[20]; 9 10 bool cmp( subject a, subject b) 11 { 12 if(a.de==b.de&&a.ne>=a.de&&b.ne<=b.de) 13 return a.ne<b.ne; 14 else if( a.de==b.de&&a.ne<=a.de&&b.ne>=b.de) 15 return a.ne<b.ne; 16 return a.de<b.de; 17 } 18 19 int main() 20 { 21 int T; 22 while( ~scanf("%d",&T)){ 23 while(T--){ 24 int n; 25 scanf("%d",&n); 26 for(int i=1;i<=n;i++){ 27 getchar(); 28 scanf("%s",s[i].name); 29 scanf("%d%d",&s[i].de,&s[i].ne); 30 } 31 sort( s+1, s+1+n, cmp); 32 33 int num=0,ti=0,ans=0,top=0,head=0,rem,tii; 34 for(int i=1;i<=n;i++){ 35 head+=s[i].ne; 36 top=s[i].de; 37 if(top<head){ 38 num++; ti=top; rem=i; tii=0; 39 for(int j=top;j<=head;j++){ 40 if((i+1)<=n&&s[i+1].de<j){ 41 i++; head+=s[i].de; 42 num++; 43 } 44 printf("%s %d\n",s[i].name,num); 45 if(tii>=s[rem].ne){ 46 rem++; tii=0; num--; 47 } 48 tii++; 49 ans+=num; 50 if(num<=0) break; 51 } 52 } 53 } 54 55 printf("%d\n",ans); 56 for(int i=1;i<=n;i++){ 57 printf("%s\n",s[i].name); 58 } 59 } 60 } 61 return 0; 62 }
就是排序,然后堆叠计算,然后直接输入排序后的结果。qwq
后面只能去搜了,唉!!!真的,什么时候凭借自己的想法做出来一波。qwq
用状压dp记录最优,代码很好理解。
代码来自:https://www.cnblogs.com/kuangbin/archive/2013/04/12/3016987.html
1 #include<cstdio> 2 using namespace std; 3 const int maxn=16; 4 const int inf=0x3f3f3f3f; 5 struct Node{ 6 char name[106]; 7 int d,c; 8 }node[maxn]; 9 int dp[1<<maxn]; 10 int pre[1<<maxn]; 11 int n; 12 13 void output(int sta) 14 { 15 if(sta==0) return ; 16 int t=0; 17 for(int i=0;i<n;i++){ 18 if((sta&(1<<i))!=0&&(pre[sta]&(1<<i))==0){ 19 t=i; break; ///当前物品有第i个,且下一个物品没有第i个的时候 20 } 21 } 22 output(pre[sta]); 23 printf("%s\n",node[t].name); 24 } 25 26 int main() 27 { 28 int T; 29 scanf("%d",&T); 30 while(T--){ 31 scanf("%d",&n); 32 for(int i=0;i<n;i++){ 33 scanf("%s%d%d",node[i].name,&node[i].d,&node[i].c); 34 } 35 for(int i=0;i<(1<<n);i++) 36 dp[i]=inf; 37 dp[0]=0; 38 for(int i=0;i<(1<<n);i++){ 39 for(int j=0;j<n;j++){ 40 if(i&(1<<j)) continue; ///在这个位置上面本来就有物品,跳过 41 int s=0; 42 for(int k=0;k<n;k++) 43 if(i&(1<<k)) s+=node[k].c; ///在该位置上面有物品就把消耗加进去 44 s+=node[j].c; ///该循环的作用主要体现在这里,要在i的基础上面把j的消耗加进去 45 if(s>node[j].d) s=s-node[j].d; ///消耗比截止的日期要大,就要相减 46 else s=0; ///消耗少比截止日期小就为0即可。 47 if(dp[i|(1<<j)]>dp[i]+s){ 48 dp[i|(1<<j)]=dp[i]+s; 49 pre[i|(1<<j)]=i; ///更新前驱 50 } 51 } 52 } 53 printf("%d\n",dp[(1<<n)-1]); 54 output((1<<n)-1); 55 } 56 return 0; 57 }
理解代码后,自己敲了一遍。感觉理解得还行。
标签:ali esc ret arch AC one 错误 bool 一个
原文地址:https://www.cnblogs.com/ZQUACM-875180305/p/9083125.html