1 条题解
-
0
C++ :
#include<cstdio> #include<cstring> using namespace std; #define min(a,b) ((a)<(b)?(a):(b)) #define inf ((1<<30)-1) int dp[2][105][1<<8][10]; int tall[105],num[1<<8]; int main() { int n,m,begin; //预处理 memset(num,0,sizeof(num)); for(int i=0; i<(1<<8); ++i) for(int j=0; j<8; ++j) if(i&(1<<j)) num[i]++; for(int cas=1;~scanf("%d%d",&n,&m);++cas) { if(n+m==0) break; begin=0;//初始高度状态 for(int i=1; i<=n; ++i) { scanf("%d",&tall[i]); tall[i]-=25; begin=begin|(1<<tall[i]); } for(int i=0; i<=m; ++i)//取走的次数 for(int j=0; j<(1<<8); ++j)//高度状态 for(int k=0; k<=8; ++k)//最后的书的高度 dp[0][i][j][k]=inf; dp[0][0][0][8]=0;//起始点 for(int i=1; i<=n; ++i) { for(int j=0; j<=m; ++j) for(int k=0; k<(1<<8); ++k) for(int s=0; s<=8; ++s) dp[i&1][j][k][s]=inf; for(int j=0; j<i&&j<=m; ++j) for(int k=0; k<(1<<8); ++k) for(int s=0; s<=8; ++s) if(dp[(i-1)&1][j][k][s]!=inf) { //取走第i位 if(j<m) dp[i&1][j+1][k][s]=min(dp[i&1][j+1][k][s],dp[(i-1)&1][j][k][s]); //不取走第i位且高度与前一个相同 if(s==tall[i]) dp[i&1][j][k][s]=min(dp[i&1][j][k][s],dp[(i-1)&1][j][k][s]); //不取走第i位且高度与前一个不同 else dp[i&1][j][k|(1<<tall[i])][tall[i]]=min(dp[i&1][j][k|(1<<tall[i])][tall[i]],dp[(i-1)&1][j][k][s]+1); } } int ans=inf; for(int i=0; i<=m; ++i) for(int j=0; j<(1<<8); ++j) for(int k=0; k<8; ++k) if(dp[n&1][i][j][k]!=inf) { int temp=j^begin;//不在此状态且拿出的书的高度 if(ans>dp[n&1][i][j][k]+num[temp]) ans=dp[n&1][i][j][k]+num[temp]; } printf("Case %d: %d\n\n",cas,ans); } return 0; }
- 1
信息
- ID
- 1830
- 时间
- 2000ms
- 内存
- 128MiB
- 难度
- (无)
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者