非單位時間任務安排問題

 1 #include <iostream>
 2 #include<string>
 3 #include<string.h>
 4 using namespace std;
 5 
 6 int main()
 7 {
 8     int n;
 9     cin>>n;
10     int s[n];
11     int j[n];
12     int c[n];
13     for(int i=0;i<n;i++)
14     {
15         cin>>s[i]>>j[i]>>c[i];
16     }
17     int temp=0;
18     for(int i=0;i<n;i++)
19     {
20         if(temp<j[i])
21             temp=j[i];
22     }
23     int a[temp+1];
24     memset(a,0,sizeof(a));
25     int y=0;
26     for(int i=1;i<=temp;i++)
27     {
28         for(int h=0;h<n;h++)
29         {
30             if(s[h]<=i&&j[h]>=i)
31             {
32                 if(a[i]>=-c[h]+a[i-s[h]])
33                 {
34                     a[i]=-c[h]+a[i-s[h]];
35                     y=h;
36                 }
37             }
38         }
39         j[y]=-1;
40     }
41     cout<<a[temp];
42 return 0;
43 }

這個代碼之因此不對就在於:ios

動態規劃算法是拿起一個東西放進子問題的最優解,但它不是最後的最優解。頗有可能在後面的某一個解中把它拿出來,很差控制能夠被選擇的物品。算法

它和動態規劃的最大不一樣就是不能自如的控制能夠被選擇的物品,一旦曾經被選擇他就不再能被選擇。spa

 

經過本身的這個算法:code

我發現blog

動態規劃和貪心算法的不一樣之處就在於進程

貪心算法一拿到就不會放,而動態規劃要放進去的。ci

個人預想是這種string

0 1 2 3 4 5 6
0 -70 -120 -160 -180 -200 -240

 

 

 

 

但結果是這種it

0 1 2 3 4 5 6
0 -70 -120 -160 -180 -200 -200

 

 

 

 

結果爲-200 是由於在5 的時候就拿了3 6 80,一旦被拿這個物品就不能被放回了io

因而在6的時候只能和5同樣

這種算法不適用於只能拿1次的狀況(有限次數更麻煩,其實也能夠等同於有限次數個拿一次的狀況)

 

 

 1 #include <iostream>
 2 #include<algorithm>
 3 using namespace std;
 4 
 5 struct thread
 6 {
 7     int s;
 8     int j;
 9     int c;
10 };
11 bool compare(thread a,thread b)
12 {
13     if(a.j<b.j)
14         return true;
15     else return false;
16 }
17 int main()
18 {
19     int n;
20     cin>>n;
21     thread m[n];
22     for(int i=0;i<n;i++)
23     {
24         cin>>m[i].s>>m[i].j>>m[i].c;
25     }
26     int temp=0;
27     for(int i=0;i<n;i++)
28     {
29         if(temp<m[i].j)
30             temp=m[i].j;
31     }
32     sort(m,m+n,compare);
33     int a[n][temp+1];
34     for(int i=0;i<=temp;i++)
35     {
36         if(i>=m[0].s)
37             a[0][i]=0;
38         else a[0][i]=m[0].c;
39     }
40     for(int i=1;i<n;i++)
41     {
42         for(int h=0;h<=temp;h++)
43         {
44             a[i][h]=a[i-1][h]+m[i].c;
45             if(h>m[i].j)
46                 a[i][h]=a[i][m[i].j];
47             else if(h>=m[i].s&&h<=m[i].j)
48             {
49                 a[i][h]=a[i][h]>a[i-1][h-m[i].s]?a[i-1][h-m[i].s]:a[i][h];
50             }
51         }
52     }
53     cout<<a[n-1][temp];
54 return 0;
55 }

 

當只能拿一次的時候,就只能這個樣子算

它想象成n*t個子問題

分別是在只有一個進程時,從零到六的每一個子問題求一遍

           在兩個進程時,從零到六每一個子問題求一遍

           在n個進程時,從零到六每一個子問題求一遍

           首先根據它的截止時間,非減排列

 

進程/時間 0 1 2 3 4 5 6
0 30 0 0 0 0 0 0
1 90 60 30 30 30 30 30
2 130 90 60 30 30 30 30
3 200 130 90 60 30 30 30
4 250 180 130 90 60 60 60
5 270 200 150 110 80 80 80
6 350 280 230 190 160 150 110

 

 

 

 

 

 

 

 

 

 

 

 

在當前幾個進程只需考慮新加進的進程

若是作 就是a[i-1][h-m[i].s]若是不作就是a[i-1][h]+m[i].c

當時間大於截止時間時,其a[i][h]=a[i][m[i].j];

相關文章
相關標籤/搜索