解题思路:动态规划 || 贪心
太水了,没想到贪心。。。还不会写贪心版。。。。动态规划的马马虎虎过。。。可能有漏洞
状态转移方程:
d[i][j] = max(d[i-1][j], d[i-1][j-1]+b[i], d[i][j-1])
条件:先按时间排序,少的在前,如果相同,罚的,大的在前
i : 第几个科目
j : 天数
b[] :罚的数量
AC代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
#define clr(p,v) memset(p,v,sizeof(p))
const int maxn = 1010 ;
int n, m, C, T;
int k, s;
int d[maxn][maxn], a[maxn], b[maxn], r[maxn];
int cmp(int x, int y)
{
if (a[x] != a[y])
return a[x] < a[y];
return b[x] > b[y];
}
int main()
{
scanf("%d", &T);
while (T--)
{
//Input
scanf("%d", &n);
clr(d, 0);
int mx = 0;
int total = 0;
for(int i=1; i<=n; ++i) r[i] = i;
for (int i=1; i<=n; ++i)
{
scanf("%d", &a[i]);
mx = max(mx, a[i]);
}
for (int i=1; i<=n; ++i)
{
scanf("%d", &b[i]);
total += b[i];
}
sort(r+1, r+n+1, cmp);
//Caculate
for (int i=1; i<=n; ++i)
{
int x = r[i];
for (int j=1; j<=a[x]; ++j)
d[i][j] = max(d[i-1][j], max(d[i][j-1], d[i-1][j-1]+b[x]));
}
//output
printf("%d\n", total - d[n][mx]);
}
return 0;
}