NC223620. KWhereHaveYouBin?
描述
输入描述
Input starts with a string of characters of length n (1 ≤ n ≤ 150) indicating the initial usage of the bins. Thecharacters will all be from the set {A, E, I, O, U, X} indicating either the company using the bin or an emptybin (X). Following this is a row of n integers indicating the number of items in each bin; values at locationscorresponding to an empty bin will always be 0 and values at locations corresponding to a company’s binwill be positive and ≤ 100. Bins for any one company will always be contiguous.The next line starts with an integer d (0 ≤ d ≤ n) indicating the number of deletions for this quarter.Following this are d integers. Each integer specifies a bin which is no longer needed by a company. None willever correspond to an already empty bin. On the final line is a positive-length string of characters indicating the new bins requested. If this string is a single X then no new bins are being requested. Otherwise thecharacters will all be in the set {A, E, I, O, U}, in no particular order, each character representing a requestfor a new bin by the corresponding company. There will always be enough bins to handle any set of changes.
输出描述
Output the minimal cost required to satisfy all the bin changes while keeping each company’s bins contiguous.
示例1
输入:
AEIOUU 1 4 6 9 2 3 1 6 A
输出:
3
示例2
输入:
AEIOUU 10 4 6 9 2 3 1 6 A
输出:
4
示例3
输入:
AEIOUU 1 4 6 9 2 3 4 5 1 4 3 EUE
输出:
0
C++ 解法, 执行用时: 9ms, 内存消耗: 1036K, 提交时间: 2021-07-23 21:08:54
#include<iostream> #include<cmath> #include<cstring> using namespace std; const int N = 160; char a[N],b[N],t[] = {'A','E','I','O','U'}; int c[N],flag[N]; int s[N]; int n,m; int d[35][N][N],dp[N][N]; int vis[N]; int main(){ scanf("%s",a + 1); n = strlen(a + 1); for(int i = 1; i <= n; i++){ cin >> c[i]; } int k; cin >> k; for(int i = 1; i <= k; i++){ int x; cin >> x; a[x] = 'X'; flag[x] = 1; } scanf("%s",b + 1); m = strlen(b + 1); for(int i = 1; i <= m; i++) s[b[i] - 'A']++; for(int i = 1; i <= n ;i++) if(!flag[i]) s[a[i] - 'A']++; int total = s['A' - 'A'] + s['E' - 'A'] + s['I' - 'A'] + s['O' - 'A'] + s['U' - 'A']; for(int j = 0; j < 5; j++) for(int l = 1; l <= n; l++){ for(int r = l; r <= n; r++){ for(int i = 1; i <= n; i++){ if(a[i] != t[j]) continue; if((i >= l && i <= r) || flag[i]) continue; d[t[j] - 'A'][l][r] += c[i]; } } } memset(dp,0x3f,sizeof dp); for(int i = 0; i <= n; i++) dp[0][i] = 0; for(int i = 1; i < (1 << 5); i++){ int sum = 0; for(int j = 0; j < 5; j++){ if(i & (1 << j)) sum += s[t[j] - 'A']; } for(int j = 0; j < 5; j++){ if(i & (1 << j)){ int g = n - (total - sum + s[t[j] - 'A']); for(int k = sum - s[t[j] - 'A']; k <= g; k++){ for(int l = s[t[j] - 'A']; l + k <= n - (total - sum); l++){ if(l == s[t[j] - 'A']) dp[i][l + k] = min(dp[i][l + k],dp[i ^ (1 << j)][k] + d[t[j] - 'A'][k + 1][k + l]); else dp[i][l + k] = min(dp[i][l + k],dp[i][l + k - 1]); } } } } } int minn = 0x3f3f3f3f; for(int i = 1; i <= n; i++) minn = min(minn,dp[(1 << 5) - 1][i]); cout << minn; return 0; }
C++(g++ 7.5.0) 解法, 执行用时: 4ms, 内存消耗: 528K, 提交时间: 2023-07-13 17:38:17
#include <bits/stdc++.h> #define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); #define xs(a) cout<<setiosflags(ios::fixed)<<setprecision(a); #define lbit(a) (__builtin_ffsll(a)) //?????1??? #define ubit(a) (64-__builtin_clzll(a)) //?????1??? #define popcount(a) __builtin_popcountll(a)//?????1??? #define mem(a,b) memset(a,b,sizeof(a)); using namespace std; #define ll long long #define endl '\n' const int N=5e2+5; const int mod=1e9+7; /*-----------------------------------------------------------------------------------------------*/ int a[N], pre[N][N]; int dp[N][N]; signed main(){IOS // mem(dp,0x3f); string s; cin>>s; int n=s.size(); s="V"+s; for(int i=1; i<=n; i++) cin>>a[i]; int m; cin>>m; for(int i=1; i<=m; i++){ int d; cin>>d; a[d]=0; s[d]='V'; } string order = "AEIOU"; //sort(order.begin(),order.end()); // string order = "UEIOA"; for(int i=1; i<=n; i++){ for(auto c:order){ pre[c][i]=pre[c][i-1]; if(s[i]==c)pre[c][i]+=a[i]; } } string t; cin>>t; map<char,int>cnt; for(auto c:t) cnt[c]++; for(auto c:s) cnt[c]++; // 5! = 120 || 120 * 10 * 150 -> 1e6 // for(auto c:order)cout<<cnt[c]<<' '; // cout<<endl; int res=2e9; do { // cout<<order<<endl; vector<vector<int>>dp(10,vector<int>(N,1e9)); //前i种字母用到位置j //dp[0][0]=0; for(int j=0; j<=n; j++)dp[0][j]=0; for(int i=1; i<=5; i++){ for(int j=1; j<=n; j++){ dp[i][j]=min(dp[i][j], dp[i][j-1]); char c=order[i-1]; int tot = cnt[c]; if(j-tot<0)continue; int num = pre[c][j] - pre[c][j-tot];// [j-tot+1,j]放字母c 已经有num代价 int val = pre[c][n] - num; //总-已有 dp[i][j]=min(dp[i][j], dp[i-1][j-tot] + val); } // for(int j=1; j<=n; j++){ // cout<<i<<' '<<j<<' '<<dp[i][j]<<endl; // } } // cout<<dp[5][n]<<endl; // for(int j=1; j<=n; j++)res=min(res,dp[5][j]); res=min(res,dp[5][n]); // break; }while(next_permutation(order.begin(),order.end())); cout<<res<<endl; return 0; }