結果
問題 | No.952 危険な火薬庫 |
ユーザー | tarattata1 |
提出日時 | 2019-12-15 22:22:10 |
言語 | C++11 (gcc 11.4.0) |
結果 |
AC
|
実行時間 | 188 ms / 2,000 ms |
コード長 | 2,723 bytes |
コンパイル時間 | 607 ms |
コンパイル使用メモリ | 77,672 KB |
実行使用メモリ | 49,408 KB |
最終ジャッジ日時 | 2024-07-02 18:24:03 |
合計ジャッジ時間 | 3,349 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
5,248 KB |
testcase_01 | AC | 2 ms
5,376 KB |
testcase_02 | AC | 2 ms
5,376 KB |
testcase_03 | AC | 139 ms
36,096 KB |
testcase_04 | AC | 133 ms
35,840 KB |
testcase_05 | AC | 107 ms
30,208 KB |
testcase_06 | AC | 163 ms
41,600 KB |
testcase_07 | AC | 56 ms
18,432 KB |
testcase_08 | AC | 183 ms
45,696 KB |
testcase_09 | AC | 188 ms
46,208 KB |
testcase_10 | AC | 73 ms
22,784 KB |
testcase_11 | AC | 2 ms
5,376 KB |
testcase_12 | AC | 78 ms
23,808 KB |
testcase_13 | AC | 82 ms
24,704 KB |
testcase_14 | AC | 20 ms
9,728 KB |
testcase_15 | AC | 119 ms
32,896 KB |
testcase_16 | AC | 26 ms
11,264 KB |
testcase_17 | AC | 20 ms
9,728 KB |
testcase_18 | AC | 35 ms
13,568 KB |
testcase_19 | AC | 3 ms
5,376 KB |
testcase_20 | AC | 2 ms
5,376 KB |
testcase_21 | AC | 71 ms
22,016 KB |
testcase_22 | AC | 17 ms
8,576 KB |
testcase_23 | AC | 3 ms
5,376 KB |
testcase_24 | AC | 8 ms
6,144 KB |
testcase_25 | AC | 172 ms
49,408 KB |
コンパイルメッセージ
main.cpp: In function ‘int main(int, char**)’: main.cpp:31:14: warning: spurious trailing ‘%’ in format [-Wformat=] 31 | scanf("%d%", &n); | ^ main.cpp:31:10: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result] 31 | scanf("%d%", &n); | ~~~~~^~~~~~~~~~~ main.cpp:35:14: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result] 35 | scanf("%lld", &A[i]); | ~~~~~^~~~~~~~~~~~~~~
ソースコード
#include <stdio.h> #include <string> #include <cstring> #include <stdlib.h> #include <math.h> #include <algorithm> #include <vector> #include <set> #include <map> #include <queue> #include <stack> #include <list> #include <iterator> #include <assert.h> #pragma warning(disable:4996) typedef long long ll; #define MIN(a, b) ((a)>(b)? (b): (a)) #define MAX(a, b) ((a)<(b)? (b): (a)) #define LINF 9223300000000000000 #define INF 2140000000 const long long MOD = 1000000007; //const long long MOD = 998244353; using namespace std; ll dp[3005][3005]; // dp[i][j] i番目(0,1,..i-1)まで見て、j個閉じている場合の危険度の最小値 int main(int argc, char* argv[]) { int n; scanf("%d%", &n); vector<ll> A(n),S(n+1); int i,j; for(i=0; i<n; i++) { scanf("%lld", &A[i]); S[i+1]=S[i]+A[i]; } vector<ll> a(n+1),b(n+1); const double eps=1e-6; for(j=0; j<=n; j++) { if(j==0) { for(i=0; i<=n; i++) { dp[i][j]=S[i]*S[i]; } } else { vector<pair<double,int> > z; // xの値, xより少し大きいところの直線のindex for(i=j; i<=n; i++) { { // for CHT a[i]=-2*S[i]; b[i]=dp[i-1][j-1]+S[i]*S[i]; while( 1 ) { if(z.empty()) { z.push_back(make_pair(-HUGE_VAL,i)); break; } else { double x0=z.back().first; int id0=z.back().second; double tmp=-(double)(b[i]-b[id0])/(a[i]-a[id0]); if(tmp<x0) { z.pop_back(); } else { z.push_back(make_pair(tmp,i)); break; } } } } if(i>j) { ll tmp=0; if(!z.empty()) { int k=lower_bound(z.begin(), z.end(), make_pair((double)S[i]+eps,-INF))-z.begin(); if(k>0) { k--; int id=z[k].second; tmp=a[id]*S[i]+b[id]; } } dp[i][j]=tmp+S[i]*S[i]; } } } } for(i=0; i<n; i++) { printf("%lld\n", dp[n][n-1-i]); } return 0; }