1. 程式人生 > >洛谷P2876 [USACO07JAN]解決問題Problem Solving

洛谷P2876 [USACO07JAN]解決問題Problem Solving

n <= 300 求最優問題 考慮動態規劃 ;

f[i][j] 是 第i個月 完成了前j個任務 

 

我們的決策有兩個 (1) 不做任務 , 光還債;(2) 做任務

然後我們寫出dp方程 (圖中sa是預付款的字首和 , sb是後付款的字首和)

  

#include<cstdio>
#include<queue>
#include<map>
#include<cstring>
#include<cstdlib>
#include<deque>
#include<iostream>
#include
<vector> #include<algorithm> #define inf 0x3f3f3f3f #define M 309 #define ll long long using namespace std; int n , a[M] , b[M] , ans , m , sa[M] , sb[M] , f[M << 1][M]; int main(){ // freopen("A.out" , "w" , stdout); // freopen("c1.in" , "r" , stdin); scanf("%d%d" , &m , &n);
for (int i = 1 ; i <= n ; ++i){ scanf("%d%d" , &a[i] , &b[i]); sa[i] = sa[i-1] + a[i] , sb[i] = sb[i-1] + b[i]; } memset(f , 0xcf , sizeof(f)); f[0][0] = m; for (int i = 1 ; i <= n * 2 + 10 ; ++i){ for (int j = 0 ; j <= n ; ++j){
if (f[i-1][j] >= 0) f[i][j] = m; } for (int j = 1 ; j <= n ; ++j){ for (int k = 0 ; k < j ; ++k){ if (f[i-1][k] >= sa[j] - sa[k] && sb[j] - sb[k] <= m){ f[i][j] = max (f[i][j] , m - sb[j] + sb[k]); } } } } for (int i = 1 ; i <= n * 2 + 5 ; ++i){ if (f[i][n] >= 0){ ans = i + 1 ; break; } } printf ("%d" , ans + 1); return 0; }