NC14845. codeJan与青蛙
描述
输入描述
第一行一个正整数T≤20表示测试组数。每组测试样例的第一行是两个正整数n,m,分别表示存在青蛙的位置和可以放置黑洞的数量。接下来n行,每行包含两个正整数a[i],b[i]分别表示第i组青蛙的位置(单位:米)和这个位置上青蛙的数量。
输出描述
对于每组测试用例用一行输出两个正整数分别表示最少可以听到多少声WA和黑洞的最少容量。用空格隔开,行末无空格。
示例1
输入:
2 3 1 1 1 2 2 3 3 3 2 1 1 4 2 2 3
输出:
8 6 3 4
说明:
对于第一个样例,只能放在 1 位置,因此听到的 WA 的次数为:1*0+2*1+3*2=8,所有青蛙汇聚在一次,容量至少为 6。C++11(clang++ 3.9) 解法, 执行用时: 10ms, 内存消耗: 508K, 提交时间: 2020-02-15 22:22:31
#include<cstdio> #include<cstring> #include<algorithm> #define N 110 using namespace std; typedef long long ll; typedef pair<ll,ll> pr; ll a[N],b[N],s1[N],s2[N]; pr f[N][N]; int id[N]; bool cmp(int x,int y) { return a[x]<a[y]; } int main() { int T; scanf("%d",&T); while(T--) { int n,m,i,j,k; scanf("%d%d",&n,&m); for(i=1;i<=n;i++) scanf("%lld%lld",&a[i],&b[i]),id[i]=i; sort(id+1,id+n+1,cmp); for(i=1;i<=n;i++) s1[i]=s1[i-1]+b[id[i]],s2[i]=s2[i-1]+a[id[i]]*b[id[i]]; memset(f,0x3f,sizeof(f)); f[0][0]=pr(0,0); for(i=1;i<=n;i++) for(j=1;j<=m;j++) for(k=0;k<i;k++) f[i][j]=min(f[i][j],pr(f[k][j-1].first+s2[i]-s2[k]-a[id[k+1]]*(s1[i]-s1[k]),max(f[k][j-1].second,s1[i]-s1[k]))); printf("%lld %lld\n",f[n][m].first,f[n][m].second); } return 0; }