NC217478. 小G的数学难题
描述
小G在APIO2021中遇到了一个数学难题,可是经过小G漫⻓的思索,发现还是始终不能窥见真谛。
具体描述下这个问题是这样的:有三个长度为的数列, , ,
2.
3.
然后题目要求小G最小化。
可是距离比赛结束只剩下半个小时了,小G现在非常着急,能否A掉这题并取得AK的好成绩拿到AU,就靠你了,加油!
输入描述
第一行一个正整数表示数据组数,。
对于每组测试数据:
第一行两个正整数,,其中,。
第二行个非负整数,第个数为。
第三行个非负整数,第个数为。
第四行个非负整数,第个数为。其中,,满足,。
输出描述
如果条件可以满足,输出最小化的值,反之输出"IMPOSSIBLE!!!"。
示例1
输入:
5 5 26 3 3 2 10 1 7 10 13 16 3 5 10 4 6 2 5 25 1 3 6 10 13 13 7 8 15 16 2 3 10 2 7 5 1 2 9 7 2 4 4 10 7 6 7 0 0 0 0 0 5 7 2 6 1 9 11 7 11 12 16 16 1 7 8 4 5 5 24 9 1 13 7 4 13 14 14 13 6 7 6 5 8 2
输出:
10 4 IMPOSSIBLE!!! 1 11
C++(clang++11) 解法, 执行用时: 285ms, 内存消耗: 39672K, 提交时间: 2021-03-27 15:20:34
#include <iostream> using namespace std; const int inf=2e9+1e5; int dp[1005][10005],a[1005],b[1005],c[1005],q[10005],head,tail; int main(int argc, char** argv) { int T; cin >> T; while(T--) { int n,p; cin >> n >> p; for(int i=1;i<=n;i++) cin >> a[i]; for(int i=1;i<=n;i++) cin >> b[i]; for(int i=1;i<=n;i++) cin >> c[i]; for(int i=1;i<=p;i++) dp[0][i]=inf; for(int i=1;i<=n;i++) { for(int j=0;j<=p;j++) dp[i][j]=dp[i-1][j]; head=1,tail=0; for(int j=a[i];j<=p;j++) { if(head<=tail&&q[head]<j-b[i]) ++head; while(head<=tail&&dp[i-1][q[tail]]>dp[i-1][j-a[i]]) --tail; q[++tail]=j-a[i]; dp[i][j]=min(dp[i][j],dp[i-1][q[head]]+c[i]); } } if(dp[n][p]>2e9) puts("IMPOSSIBLE!!!"); else cout << dp[n][p] << "\n"; } return 0; }