标签:poj ace c++ one ret min div 编号 printf
题目链接:https://vjudge.net/problem/LightOJ-1422
简单题意:参加n场舞会,编号为i的场次需要穿衣服i。衣服可以叠着穿,只看最外层的衣服,而且脱下后不能再穿。求最少要买的衣服数
不太能想到这是个区间dp吧,而且方程和以前做的简单区间dp(能量项链,poj2955,poj1651)的转移方程不太像,完全想偏了,还再想怎么由左右+-1的子区间转移......实际上是这样的:设f[i][j]表示从舞会i到j需要买的最少衣服数。考虑第j件衣服。如果买新的,f[i][j]=f[i][j-1]+1;如果不买,那么对于1<=k<=j-1而且a[j]=a[k]的k(找到一件编号和j相同的衣服,从k到j将它一直穿在里层),f[i][j]=min(f[i][j],f[i][k]+f[k+1][j-1])
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 int t,n,i,j,k,l,num; 5 int f[110][110],a[110]; 6 7 void solve(){ 8 for (i=1;i<=n;i++) f[i][i]=1; 9 for (i=1;i<=n-1;i++) f[i][i+1]=(a[i]==a[i+1])?1:2; 10 for (l=1;l<=n;l++) 11 for (i=1;i<=n;i++){ 12 j=i+l; 13 if (j>n) continue; 14 f[i][j]=f[i][j-1]+1; 15 for (k=i;k<=j-1;k++) 16 if (a[j]==a[k]) f[i][j]=min(f[i][j],f[i][k]+f[k+1][j-1]); //* 17 } 18 printf("Case %d: %d\n",num,f[1][n]); 19 } 20 21 int main(){ 22 scanf("%d",&t); 23 while (t--){ 24 num++; 25 scanf("%d",&n); 26 for (i=1;i<=n;i++) scanf("%d",&a[i]); 27 solve(); 28 } 29 //system("pause"); 30 return 0; 31 }
lightoj1422 Halloween Costumes
标签:poj ace c++ one ret min div 编号 printf
原文地址:https://www.cnblogs.com/edmunds/p/13236728.html