Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C++

ค้นหา Derangement ของ Array ใน C++


สมมติว่าเรามีอาร์เรย์ที่ประกอบด้วย n ตัวเลขจาก 1 ถึง n เพิ่มขึ้น เราต้องหาจำนวนของความผิดปกติที่มันสามารถสร้างได้

เรารู้ว่าในคณิตศาสตร์แบบผสมผสาน ความคลาดเคลื่อนคือการเรียงสับเปลี่ยนขององค์ประกอบของเซต โดยที่องค์ประกอบจะไม่ปรากฏในตำแหน่งเดิม คำตอบอาจมีขนาดใหญ่มาก ดังนั้นให้ส่งคืน mod เอาต์พุต 10^9 + 7

ดังนั้น ถ้าอินพุตเท่ากับ 3 เอาต์พุตจะเป็น 2 เนื่องจากอาร์เรย์ดั้งเดิมคือ [1,2,3] ความแปรปรวนสองอย่างคือ [2,3,1] และ [3,1,2].

เพื่อแก้ปัญหานี้ เราจะทำตามขั้นตอนเหล่านี้ -

  • ม :=10^9 + 7

  • กำหนดฟังก์ชัน add() ซึ่งจะใช้เวลา a, b,

  • กลับ ((a mod m) + (b mod m)) mod m

  • กำหนดฟังก์ชัน mul() ซึ่งจะใช้ a, b,

  • กลับ ((a mod m) * (b mod m)) mod m

  • จากวิธีหลักให้ทำดังนี้

  • ยกเลิก :=0

  • ถ้า n เท่ากับ 1 แล้ว −

    • คืนค่า 0

  • ถ้า n เท่ากับ 2 แล้ว −

    • กลับ 1

  • กำหนดขนาดอาร์เรย์ dp (n + 1)

  • dp[2] :=1

  • สำหรับการเริ่มต้น i :=3 เมื่อฉัน <=n อัปเดต (เพิ่ม i ขึ้น 1) ทำ -

    • dp[i] :=mul(i - 1, add(dp[i - 2], dp[i - 1]))

  • กลับ dp[n]

ตัวอย่าง

ให้เราดูการใช้งานต่อไปนี้เพื่อความเข้าใจที่ดีขึ้น -

#include <bits/stdc++.h>
using namespace std;
typedef long long int lli;
const lli m = 1e9 + 7;
lli add(lli a, lli b){
   return ((a % m) + (b % m)) % m;
}
lli mul(lli a, lli b){
   return ((a % m) * (b % m)) % m;
}
class Solution {
public:
   int findDerangement(int n) {
      int ret = 0;
      if (n == 1)
         return 0;
      if (n == 2)
         return 1;
      vector dp(n + 1);
      dp[2] = 1;
      for (int i = 3; i <= n; i++) {
         dp[i] = mul(i - 1, add(dp[i - 2], dp[i - 1]));
      }
      return dp[n];
   }
};
main(){
   Solution ob;
   cout<<(ob.findDerangement(3));
}

อินพุต

3

ผลลัพธ์

2